diff options
223 files changed, 6172 insertions, 3973 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index d01e183df84d..30c2c69e8572 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -252,6 +252,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/overlay/ExperimentNavigation $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/overlay/ExperimentNavigationBarSlim) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/ExperimentNavigationBarSlim) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/SystemUI) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/api/current.txt b/api/current.txt index a56b097f5578..850d9aceb87b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5385,11 +5385,11 @@ package android.app { method public android.graphics.drawable.Icon getIcon(); method public android.app.RemoteInput[] getRemoteInputs(); method public int getSemanticAction(); + method public boolean isContextual(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR; field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5 field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa - field public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11; // 0xb field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4 field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2 field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3 @@ -5414,6 +5414,7 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender); method public android.os.Bundle getExtras(); method public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean); + method public android.app.Notification.Action.Builder setContextual(boolean); method public android.app.Notification.Action.Builder setSemanticAction(int); } @@ -11600,6 +11601,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone"; field public static final java.lang.String FEATURE_MIDI = "android.software.midi"; field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc"; + field public static final java.lang.String FEATURE_NFC_BEAM = "android.sofware.nfc.beam"; field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce"; field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef"; field public static final java.lang.String FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE = "android.hardware.nfc.ese"; @@ -24943,6 +24945,25 @@ package android.media { field public static final int TYPE_STRING = 4; // 0x4 } + public final class MediaItem2 implements android.os.Parcelable { + method public int describeContents(); + method public long getEndPosition(); + method public android.media.MediaMetadata getMetadata(); + method public long getStartPosition(); + method public void setMetadata(android.media.MediaMetadata); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.media.MediaItem2> CREATOR; + field public static final long POSITION_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL + } + + public static class MediaItem2.Builder { + ctor public MediaItem2.Builder(); + method public android.media.MediaItem2 build(); + method public android.media.MediaItem2.Builder setEndPosition(long); + method public android.media.MediaItem2.Builder setMetadata(android.media.MediaMetadata); + method public android.media.MediaItem2.Builder setStartPosition(long); + } + public final class MediaMetadata implements android.os.Parcelable { method public boolean containsKey(java.lang.String); method public int describeContents(); @@ -30017,6 +30038,7 @@ package android.net.wifi.p2p { ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup); method public int describeContents(); method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList(); + method public int getFrequency(); method public java.lang.String getInterface(); method public java.lang.String getNetworkName(); method public android.net.wifi.p2p.WifiP2pDevice getOwner(); @@ -30295,14 +30317,14 @@ package android.nfc { method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); method public java.util.List<java.lang.String> getSupportedOffHostSecureElements(); method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler); - method public boolean invokeBeam(android.app.Activity); + method public deprecated boolean invokeBeam(android.app.Activity); method public boolean isEnabled(); - method public boolean isNdefPushEnabled(); - method public void setBeamPushUris(android.net.Uri[], android.app.Activity); - method public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity); - method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); - method public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...); - method public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...); + method public deprecated boolean isNdefPushEnabled(); + method public deprecated void setBeamPushUris(android.net.Uri[], android.app.Activity); + method public deprecated void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity); + method public deprecated void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); + method public deprecated void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...); + method public deprecated void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...); field public static final java.lang.String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED"; field public static final java.lang.String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; field public static final java.lang.String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; @@ -30329,15 +30351,15 @@ package android.nfc { field public static final int STATE_TURNING_ON = 2; // 0x2 } - public static abstract interface NfcAdapter.CreateBeamUrisCallback { + public static abstract deprecated interface NfcAdapter.CreateBeamUrisCallback { method public abstract android.net.Uri[] createBeamUris(android.nfc.NfcEvent); } - public static abstract interface NfcAdapter.CreateNdefMessageCallback { + public static abstract deprecated interface NfcAdapter.CreateNdefMessageCallback { method public abstract android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent); } - public static abstract interface NfcAdapter.OnNdefPushCompleteCallback { + public static abstract deprecated interface NfcAdapter.OnNdefPushCompleteCallback { method public abstract void onNdefPushComplete(android.nfc.NfcEvent); } @@ -37865,7 +37887,11 @@ package android.provider { method public static java.lang.String getVolumeName(android.net.Uri); method public static android.provider.MediaStore.PendingSession openPending(android.content.Context, android.net.Uri); method public static android.net.Uri setIncludePending(android.net.Uri); + method public static android.net.Uri setIncludeTrashed(android.net.Uri); method public static android.net.Uri setRequireOriginal(android.net.Uri); + method public static void trash(android.content.Context, android.net.Uri); + method public static void trash(android.content.Context, android.net.Uri, long); + method public static void untrash(android.content.Context, android.net.Uri); field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"; field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE"; field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW"; @@ -38044,6 +38070,7 @@ package android.provider { } public static abstract interface MediaStore.DownloadColumns implements android.provider.MediaStore.MediaColumns { + field public static final java.lang.String DESCRIPTION = "description"; field public static final java.lang.String DOWNLOAD_URI = "download_uri"; field public static final java.lang.String REFERER_URI = "referer_uri"; } @@ -38088,6 +38115,7 @@ package android.provider { field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic"; field public static final java.lang.String ORIENTATION = "orientation"; field public static final deprecated java.lang.String PICASA_ID = "picasa_id"; + field public static final java.lang.String SECONDARY_BUCKET_ID = "secondary_bucket_id"; } public static final class MediaStore.Images.Media implements android.provider.MediaStore.Images.ImageColumns { @@ -38132,11 +38160,13 @@ package android.provider { public static abstract interface MediaStore.MediaColumns implements android.provider.BaseColumns { field public static final deprecated java.lang.String DATA = "_data"; field public static final java.lang.String DATE_ADDED = "date_added"; + field public static final java.lang.String DATE_EXPIRES = "date_expires"; field public static final java.lang.String DATE_MODIFIED = "date_modified"; field public static final java.lang.String DISPLAY_NAME = "_display_name"; field public static final java.lang.String HASH = "_hash"; field public static final java.lang.String HEIGHT = "height"; field public static final java.lang.String IS_PENDING = "is_pending"; + field public static final java.lang.String IS_TRASHED = "is_trashed"; field public static final java.lang.String MIME_TYPE = "mime_type"; field public static final java.lang.String OWNER_PACKAGE_NAME = "owner_package_name"; field public static final java.lang.String SIZE = "_size"; @@ -38212,6 +38242,7 @@ package android.provider { field public static final deprecated java.lang.String LONGITUDE = "longitude"; field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic"; field public static final java.lang.String RESOLUTION = "resolution"; + field public static final java.lang.String SECONDARY_BUCKET_ID = "secondary_bucket_id"; field public static final java.lang.String TAGS = "tags"; } diff --git a/api/system-current.txt b/api/system-current.txt index 10d483d1bfce..e99ac06c258e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1512,8 +1512,6 @@ package android.hardware.display { public final class BrightnessConfiguration implements android.os.Parcelable { method public int describeContents(); - method public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int); - method public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(java.lang.String); method public android.util.Pair<float[], float[]> getCurve(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR; @@ -1521,22 +1519,10 @@ package android.hardware.display { public static class BrightnessConfiguration.Builder { ctor public BrightnessConfiguration.Builder(float[], float[]); - method public android.hardware.display.BrightnessConfiguration.Builder addCorrectionByCategory(int, android.hardware.display.BrightnessCorrection); - method public android.hardware.display.BrightnessConfiguration.Builder addCorrectionByPackageName(java.lang.String, android.hardware.display.BrightnessCorrection); method public android.hardware.display.BrightnessConfiguration build(); - method public int getMaxCorrectionsByCategory(); - method public int getMaxCorrectionsByPackageName(); method public android.hardware.display.BrightnessConfiguration.Builder setDescription(java.lang.String); } - public final class BrightnessCorrection implements android.os.Parcelable { - method public float apply(float); - method public static android.hardware.display.BrightnessCorrection createScaleAndTranslateLog(float, float); - method public int describeContents(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessCorrection> CREATOR; - } - public final class DisplayManager { method public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats(); method public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration(); @@ -3909,7 +3895,6 @@ package android.net.wifi { method public void disable(int, android.net.wifi.WifiManager.ActionListener); method public void disableEphemeralNetwork(java.lang.String); method public void forget(int, android.net.wifi.WifiManager.ActionListener); - method public java.util.List<android.net.wifi.WifiConfiguration> getAllMatchingWifiConfigs(java.util.List<android.net.wifi.ScanResult>); method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks(); method public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method public int getWifiApState(); @@ -4602,6 +4587,7 @@ package android.os.storage { method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException; method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException; method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException; + method public static boolean hasIsolatedStorage(); field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1 } diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 7a993fd946f7..041fbfaff23d 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -2837,8 +2837,6 @@ Lcom/android/internal/telephony/dataconnection/DcTracker;->mProvisioningSpinner: Lcom/android/internal/telephony/dataconnection/DcTracker;->mResolver:Landroid/content/ContentResolver; Lcom/android/internal/telephony/dataconnection/DcTracker;->mState:Lcom/android/internal/telephony/DctConstants$State; Lcom/android/internal/telephony/dataconnection/DcTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager; -Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyDataConnection(Ljava/lang/String;)V -Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyOffApnsOfAvailability(Ljava/lang/String;)V Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V @@ -3290,7 +3288,7 @@ Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/o Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellInfo(Ljava/util/List;)V -Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;Ljava/lang/String;)V +Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;)V Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager; Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 0b5776e89524..57132a72700d 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -37,6 +37,7 @@ import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceSession; import android.view.SurfaceView; +import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -320,7 +321,7 @@ public class ActivityView extends ViewGroup { public void surfaceCreated(SurfaceHolder surfaceHolder) { mTmpSurface = new Surface(); if (mVirtualDisplay == null) { - initVirtualDisplay(new SurfaceSession(surfaceHolder.getSurface())); + initVirtualDisplay(new SurfaceSession()); if (mVirtualDisplay != null && mActivityViewCallback != null) { mActivityViewCallback.onActivityViewReady(ActivityView.this); } @@ -354,6 +355,12 @@ public class ActivityView extends ViewGroup { } } + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + mSurfaceView.setVisibility(visibility); + } + private void initVirtualDisplay(SurfaceSession surfaceSession) { if (mVirtualDisplay != null) { throw new IllegalStateException("Trying to initialize for the second time."); @@ -382,6 +389,7 @@ public class ActivityView extends ViewGroup { mRootSurfaceControl = new SurfaceControl.Builder(surfaceSession) .setContainerLayer(true) + .setParent(mSurfaceView.getSurfaceControl()) .setName(DISPLAY_NAME) .build(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index e066f06542c3..b657a916604b 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1427,18 +1427,13 @@ public class Notification implements Parcelable */ public static final int SEMANTIC_ACTION_CALL = 10; - /** - * {@code SemanticAction}: Contextual action - dependent on the current notification. E.g. - * open a Map application with an address shown in the notification. - */ - public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11; - private final Bundle mExtras; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private Icon mIcon; private final RemoteInput[] mRemoteInputs; private boolean mAllowGeneratedReplies = true; private final @SemanticAction int mSemanticAction; + private final boolean mIsContextual; /** * Small icon representing the action. @@ -1474,6 +1469,7 @@ public class Notification implements Parcelable mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR); mAllowGeneratedReplies = in.readInt() == 1; mSemanticAction = in.readInt(); + mIsContextual = in.readInt() == 1; } /** @@ -1482,13 +1478,13 @@ public class Notification implements Parcelable @Deprecated public Action(int icon, CharSequence title, PendingIntent intent) { this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true, - SEMANTIC_ACTION_NONE); + SEMANTIC_ACTION_NONE, false /* isContextual */); } /** Keep in sync with {@link Notification.Action.Builder#Builder(Action)}! */ private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs, boolean allowGeneratedReplies, - @SemanticAction int semanticAction) { + @SemanticAction int semanticAction, boolean isContextual) { this.mIcon = icon; if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) { this.icon = icon.getResId(); @@ -1499,6 +1495,7 @@ public class Notification implements Parcelable this.mRemoteInputs = remoteInputs; this.mAllowGeneratedReplies = allowGeneratedReplies; this.mSemanticAction = semanticAction; + this.mIsContextual = isContextual; } /** @@ -1546,6 +1543,15 @@ public class Notification implements Parcelable } /** + * Returns whether this is a contextual Action, i.e. whether the action is dependent on the + * notification message body. An example of a contextual action could be an action opening a + * map application with an address shown in the notification. + */ + public boolean isContextual() { + return mIsContextual; + } + + /** * Get the list of inputs to be collected from the user that ONLY accept data when this * action is sent. These remote inputs are guaranteed to return true on a call to * {@link RemoteInput#isDataOnly}. @@ -1570,6 +1576,7 @@ public class Notification implements Parcelable private final Bundle mExtras; private ArrayList<RemoteInput> mRemoteInputs; private @SemanticAction int mSemanticAction; + private boolean mIsContextual; /** * Construct a new builder for {@link Action} object. @@ -1684,6 +1691,16 @@ public class Notification implements Parcelable } /** + * Sets whether this {@link Action} is a contextual action, i.e. whether the action is + * dependent on the notification message body. An example of a contextual action could + * be an action opening a map application with an address shown in the notification. + */ + public Builder setContextual(boolean isContextual) { + mIsContextual = isContextual; + return this; + } + + /** * Apply an extender to this action builder. Extenders may be used to add * metadata or change options on this builder. */ @@ -1697,7 +1714,7 @@ public class Notification implements Parcelable * necessary to display the action. */ private void checkContextualActionNullFields() { - if (mSemanticAction != SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) return; + if (!mIsContextual) return; if (mIcon == null) { throw new NullPointerException("Contextual Actions must contain a valid icon"); @@ -1743,7 +1760,7 @@ public class Notification implements Parcelable RemoteInput[] textInputsArr = textInputs.isEmpty() ? null : textInputs.toArray(new RemoteInput[textInputs.size()]); return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr, - mAllowGeneratedReplies, mSemanticAction); + mAllowGeneratedReplies, mSemanticAction, mIsContextual); } } @@ -1756,7 +1773,8 @@ public class Notification implements Parcelable mExtras == null ? new Bundle() : new Bundle(mExtras), getRemoteInputs(), getAllowGeneratedReplies(), - getSemanticAction()); + getSemanticAction(), + isContextual()); } @Override @@ -1784,6 +1802,7 @@ public class Notification implements Parcelable out.writeTypedArray(mRemoteInputs, flags); out.writeInt(mAllowGeneratedReplies ? 1 : 0); out.writeInt(mSemanticAction); + out.writeInt(mIsContextual ? 1 : 0); } public static final Parcelable.Creator<Action> CREATOR = @@ -2073,8 +2092,7 @@ public class Notification implements Parcelable SEMANTIC_ACTION_UNMUTE, SEMANTIC_ACTION_THUMBS_UP, SEMANTIC_ACTION_THUMBS_DOWN, - SEMANTIC_ACTION_CALL, - SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION + SEMANTIC_ACTION_CALL }) @Retention(RetentionPolicy.SOURCE) public @interface SemanticAction {} @@ -3230,8 +3248,7 @@ public class Notification implements Parcelable } /** - * Returns the actions that are contextual (marked as SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) out - * of the actions in this notification. + * Returns the actions that are contextual out of the actions in this notification. * * @hide */ @@ -3240,8 +3257,7 @@ public class Notification implements Parcelable List<Notification.Action> contextualActions = new ArrayList<>(); for (Notification.Action action : actions) { - if (action.getSemanticAction() - == Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) { + if (action.isContextual()) { contextualActions.add(action); } } @@ -5062,8 +5078,7 @@ public class Notification implements Parcelable List<Notification.Action> actions) { List<Notification.Action> nonContextualActions = new ArrayList<>(); for (Notification.Action action : actions) { - if (action.getSemanticAction() - != Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) { + if (!action.isContextual()) { nonContextualActions.add(action); } } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 7ebe6ecbf502..2aeb68da365b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1956,6 +1956,13 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The Beam API is enabled on the device. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_NFC_BEAM = "android.sofware.nfc.beam"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device supports any * one of the {@link #FEATURE_NFC}, {@link #FEATURE_NFC_HOST_CARD_EMULATION}, * or {@link #FEATURE_NFC_HOST_CARD_EMULATION_NFCF} features. diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java index be054297c769..7e52ca331f9f 100644 --- a/core/java/android/hardware/display/BrightnessConfiguration.java +++ b/core/java/android/hardware/display/BrightnessConfiguration.java @@ -19,54 +19,26 @@ package android.hardware.display; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.content.pm.ApplicationInfo; import android.os.Parcel; import android.os.Parcelable; import android.util.Pair; import com.android.internal.util.Preconditions; -import com.android.internal.util.XmlUtils; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Objects; /** @hide */ @SystemApi @TestApi public final class BrightnessConfiguration implements Parcelable { - private static final String TAG_BRIGHTNESS_CURVE = "brightness-curve"; - private static final String TAG_BRIGHTNESS_POINT = "brightness-point"; - private static final String TAG_BRIGHTNESS_CORRECTIONS = "brightness-corrections"; - private static final String TAG_BRIGHTNESS_CORRECTION = "brightness-correction"; - private static final String ATTR_LUX = "lux"; - private static final String ATTR_NITS = "nits"; - private static final String ATTR_DESCRIPTION = "description"; - private static final String ATTR_PACKAGE_NAME = "package-name"; - private static final String ATTR_CATEGORY = "category"; - private final float[] mLux; private final float[] mNits; - private final Map<String, BrightnessCorrection> mCorrectionsByPackageName; - private final Map<Integer, BrightnessCorrection> mCorrectionsByCategory; private final String mDescription; - private BrightnessConfiguration(float[] lux, float[] nits, - Map<String, BrightnessCorrection> correctionsByPackageName, - Map<Integer, BrightnessCorrection> correctionsByCategory, String description) { + private BrightnessConfiguration(float[] lux, float[] nits, String description) { mLux = lux; mNits = nits; - mCorrectionsByPackageName = correctionsByPackageName; - mCorrectionsByCategory = correctionsByCategory; mDescription = description; } @@ -84,38 +56,6 @@ public final class BrightnessConfiguration implements Parcelable { } /** - * Returns a brightness correction by app, or null. - * - * @param packageName - * The app's package name. - * - * @return The matching brightness correction, or null. - * - * @hide - */ - @SystemApi - @Nullable - public BrightnessCorrection getCorrectionByPackageName(String packageName) { - return mCorrectionsByPackageName.get(packageName); - } - - /** - * Returns a brightness correction by app category, or null. - * - * @param category - * The app category. - * - * @return The matching brightness correction, or null. - * - * @hide - */ - @SystemApi - @Nullable - public BrightnessCorrection getCorrectionByCategory(int category) { - return mCorrectionsByCategory.get(category); - } - - /** * Returns description string. * @hide */ @@ -127,20 +67,6 @@ public final class BrightnessConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeFloatArray(mLux); dest.writeFloatArray(mNits); - dest.writeInt(mCorrectionsByPackageName.size()); - for (Entry<String, BrightnessCorrection> entry : mCorrectionsByPackageName.entrySet()) { - final String packageName = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - dest.writeString(packageName); - correction.writeToParcel(dest, flags); - } - dest.writeInt(mCorrectionsByCategory.size()); - for (Entry<Integer, BrightnessCorrection> entry : mCorrectionsByCategory.entrySet()) { - final int category = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - dest.writeInt(category); - correction.writeToParcel(dest, flags); - } dest.writeString(mDescription); } @@ -159,14 +85,7 @@ public final class BrightnessConfiguration implements Parcelable { } sb.append("(").append(mLux[i]).append(", ").append(mNits[i]).append(")"); } - sb.append("], {"); - for (Entry<String, BrightnessCorrection> entry : mCorrectionsByPackageName.entrySet()) { - sb.append("'" + entry.getKey() + "': " + entry.getValue() + ", "); - } - for (Entry<Integer, BrightnessCorrection> entry : mCorrectionsByCategory.entrySet()) { - sb.append(entry.getKey() + ": " + entry.getValue() + ", "); - } - sb.append("}, '"); + sb.append("], '"); if (mDescription != null) { sb.append(mDescription); } @@ -179,8 +98,6 @@ public final class BrightnessConfiguration implements Parcelable { int result = 1; result = result * 31 + Arrays.hashCode(mLux); result = result * 31 + Arrays.hashCode(mNits); - result = result * 31 + mCorrectionsByPackageName.hashCode(); - result = result * 31 + mCorrectionsByCategory.hashCode(); if (mDescription != null) { result = result * 31 + mDescription.hashCode(); } @@ -197,8 +114,6 @@ public final class BrightnessConfiguration implements Parcelable { } final BrightnessConfiguration other = (BrightnessConfiguration) o; return Arrays.equals(mLux, other.mLux) && Arrays.equals(mNits, other.mNits) - && mCorrectionsByPackageName.equals(other.mCorrectionsByPackageName) - && mCorrectionsByCategory.equals(other.mCorrectionsByCategory) && Objects.equals(mDescription, other.mDescription); } @@ -208,25 +123,7 @@ public final class BrightnessConfiguration implements Parcelable { float[] lux = in.createFloatArray(); float[] nits = in.createFloatArray(); Builder builder = new Builder(lux, nits); - - int n = in.readInt(); - for (int i = 0; i < n; i++) { - final String packageName = in.readString(); - final BrightnessCorrection correction = - BrightnessCorrection.CREATOR.createFromParcel(in); - builder.addCorrectionByPackageName(packageName, correction); - } - - n = in.readInt(); - for (int i = 0; i < n; i++) { - final int category = in.readInt(); - final BrightnessCorrection correction = - BrightnessCorrection.CREATOR.createFromParcel(in); - builder.addCorrectionByCategory(category, correction); - } - - final String description = in.readString(); - builder.setDescription(description); + builder.setDescription(in.readString()); return builder.build(); } @@ -236,146 +133,11 @@ public final class BrightnessConfiguration implements Parcelable { }; /** - * Writes the configuration to an XML serializer. - * - * @param serializer - * The XML serializer. - * - * @hide - */ - public void saveToXml(XmlSerializer serializer) throws IOException { - serializer.startTag(null, TAG_BRIGHTNESS_CURVE); - if (mDescription != null) { - serializer.attribute(null, ATTR_DESCRIPTION, mDescription); - } - for (int i = 0; i < mLux.length; i++) { - serializer.startTag(null, TAG_BRIGHTNESS_POINT); - serializer.attribute(null, ATTR_LUX, Float.toString(mLux[i])); - serializer.attribute(null, ATTR_NITS, Float.toString(mNits[i])); - serializer.endTag(null, TAG_BRIGHTNESS_POINT); - } - serializer.endTag(null, TAG_BRIGHTNESS_CURVE); - serializer.startTag(null, TAG_BRIGHTNESS_CORRECTIONS); - for (Map.Entry<String, BrightnessCorrection> entry : - mCorrectionsByPackageName.entrySet()) { - final String packageName = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - serializer.startTag(null, TAG_BRIGHTNESS_CORRECTION); - serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); - correction.saveToXml(serializer); - serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION); - } - for (Map.Entry<Integer, BrightnessCorrection> entry : mCorrectionsByCategory.entrySet()) { - final int category = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - serializer.startTag(null, TAG_BRIGHTNESS_CORRECTION); - serializer.attribute(null, ATTR_CATEGORY, Integer.toString(category)); - correction.saveToXml(serializer); - serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION); - } - serializer.endTag(null, TAG_BRIGHTNESS_CORRECTIONS); - } - - /** - * Read a configuration from an XML parser. - * - * @param parser - * The XML parser. - * - * @throws IOException - * The parser failed to read the XML file. - * @throws XmlPullParserException - * The parser failed to parse the XML file. - * - * @hide - */ - public static BrightnessConfiguration loadFromXml(XmlPullParser parser) - throws IOException, XmlPullParserException { - String description = null; - List<Float> luxList = new ArrayList<>(); - List<Float> nitsList = new ArrayList<>(); - Map<String, BrightnessCorrection> correctionsByPackageName = new HashMap<>(); - Map<Integer, BrightnessCorrection> correctionsByCategory = new HashMap<>(); - final int configDepth = parser.getDepth(); - while (XmlUtils.nextElementWithin(parser, configDepth)) { - if (TAG_BRIGHTNESS_CURVE.equals(parser.getName())) { - description = parser.getAttributeValue(null, ATTR_DESCRIPTION); - final int curveDepth = parser.getDepth(); - while (XmlUtils.nextElementWithin(parser, curveDepth)) { - if (!TAG_BRIGHTNESS_POINT.equals(parser.getName())) { - continue; - } - final float lux = loadFloatFromXml(parser, ATTR_LUX); - final float nits = loadFloatFromXml(parser, ATTR_NITS); - luxList.add(lux); - nitsList.add(nits); - } - } - if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) { - final int correctionsDepth = parser.getDepth(); - while (XmlUtils.nextElementWithin(parser, correctionsDepth)) { - if (!TAG_BRIGHTNESS_CORRECTION.equals(parser.getName())) { - continue; - } - final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); - final String categoryText = parser.getAttributeValue(null, ATTR_CATEGORY); - BrightnessCorrection correction = BrightnessCorrection.loadFromXml(parser); - if (packageName != null) { - correctionsByPackageName.put(packageName, correction); - } else if (categoryText != null) { - try { - final int category = Integer.parseInt(categoryText); - correctionsByCategory.put(category, correction); - } catch (NullPointerException | NumberFormatException e) { - continue; - } - } - } - } - } - final int n = luxList.size(); - float[] lux = new float[n]; - float[] nits = new float[n]; - for (int i = 0; i < n; i++) { - lux[i] = luxList.get(i); - nits[i] = nitsList.get(i); - } - final BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(lux, - nits); - builder.setDescription(description); - for (Map.Entry<String, BrightnessCorrection> entry : correctionsByPackageName.entrySet()) { - final String packageName = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - builder.addCorrectionByPackageName(packageName, correction); - } - for (Map.Entry<Integer, BrightnessCorrection> entry : correctionsByCategory.entrySet()) { - final int category = entry.getKey(); - final BrightnessCorrection correction = entry.getValue(); - builder.addCorrectionByCategory(category, correction); - } - return builder.build(); - } - - private static float loadFloatFromXml(XmlPullParser parser, String attribute) { - final String string = parser.getAttributeValue(null, attribute); - try { - return Float.parseFloat(string); - } catch (NullPointerException | NumberFormatException e) { - return Float.NaN; - } - } - - /** * A builder class for {@link BrightnessConfiguration}s. */ public static class Builder { - private static final int MAX_CORRECTIONS_BY_PACKAGE_NAME = 20; - private static final int MAX_CORRECTIONS_BY_CATEGORY = 20; - private float[] mCurveLux; private float[] mCurveNits; - private Map<String, BrightnessCorrection> mCorrectionsByPackageName; - private Map<Integer, BrightnessCorrection> mCorrectionsByCategory; private String mDescription; /** @@ -407,88 +169,6 @@ public final class BrightnessConfiguration implements Parcelable { checkMonotonic(nits, false /*strictly increasing*/, "nits"); mCurveLux = lux; mCurveNits = nits; - mCorrectionsByPackageName = new HashMap<>(); - mCorrectionsByCategory = new HashMap<>(); - } - - /** - * Returns the maximum number of corrections by package name allowed. - * - * @return The maximum number of corrections by package name allowed. - * - * @hide - */ - @SystemApi - public int getMaxCorrectionsByPackageName() { - return MAX_CORRECTIONS_BY_PACKAGE_NAME; - } - - /** - * Returns the maximum number of corrections by category allowed. - * - * @return The maximum number of corrections by category allowed. - * - * @hide - */ - @SystemApi - public int getMaxCorrectionsByCategory() { - return MAX_CORRECTIONS_BY_CATEGORY; - } - - /** - * Add a brightness correction by app package name. - * This correction is applied whenever an app with this package name has the top activity - * of the focused stack. - * - * @param packageName - * The app's package name. - * @param correction - * The brightness correction. - * - * @return The builder. - * - * @throws IllegalArgumentExceptions - * Maximum number of corrections by package name exceeded (see - * {@link #getMaxCorrectionsByPackageName}). - * - * @hide - */ - @SystemApi - public Builder addCorrectionByPackageName(String packageName, - BrightnessCorrection correction) { - if (mCorrectionsByPackageName.size() >= getMaxCorrectionsByPackageName()) { - throw new IllegalArgumentException("Too many corrections by package name"); - } - mCorrectionsByPackageName.put(packageName, correction); - return this; - } - - /** - * Add a brightness correction by app category. - * This correction is applied whenever an app with this category has the top activity of - * the focused stack, and only if a correction by package name has not been applied. - * - * @param category - * The {@link android.content.pm.ApplicationInfo#category app category}. - * @param correction - * The brightness correction. - * - * @return The builder. - * - * @throws IllegalArgumentException - * Maximum number of corrections by category exceeded (see - * {@link #getMaxCorrectionsByCategory}). - * - * @hide - */ - @SystemApi - public Builder addCorrectionByCategory(@ApplicationInfo.Category int category, - BrightnessCorrection correction) { - if (mCorrectionsByCategory.size() >= getMaxCorrectionsByCategory()) { - throw new IllegalArgumentException("Too many corrections by category"); - } - mCorrectionsByCategory.put(category, correction); - return this; } /** @@ -511,8 +191,7 @@ public final class BrightnessConfiguration implements Parcelable { if (mCurveLux == null || mCurveNits == null) { throw new IllegalStateException("A curve must be set!"); } - return new BrightnessConfiguration(mCurveLux, mCurveNits, mCorrectionsByPackageName, - mCorrectionsByCategory, mDescription); + return new BrightnessConfiguration(mCurveLux, mCurveNits, mDescription); } private static void checkMonotonic(float[] vals, boolean strictlyIncreasing, String name) { diff --git a/core/java/android/hardware/display/BrightnessCorrection.java b/core/java/android/hardware/display/BrightnessCorrection.java deleted file mode 100644 index c4e0e3b723cd..000000000000 --- a/core/java/android/hardware/display/BrightnessCorrection.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.display; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.MathUtils; - -import com.android.internal.util.XmlUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.IOException; - -/** - * BrightnessCorrection encapsulates a correction to the brightness, without comitting to the - * actual correction scheme. - * It is used by the BrightnessConfiguration, which maps context (e.g. the foreground app's package - * name and category) to corrections that need to be applied to the brightness within that context. - * Corrections are currently done by the app that has the top activity of the focused stack, either - * by its package name, or (if its package name is not mapped to any correction) by its category. - * - * @hide - */ -@SystemApi -public final class BrightnessCorrection implements Parcelable { - - private static final int SCALE_AND_TRANSLATE_LOG = 1; - - private static final String TAG_SCALE_AND_TRANSLATE_LOG = "scale-and-translate-log"; - - private BrightnessCorrectionImplementation mImplementation; - - // Parcelable classes must be final, and protected methods are not allowed in APIs, so we can't - // make this class abstract and use composition instead of inheritence. - private BrightnessCorrection(BrightnessCorrectionImplementation implementation) { - mImplementation = implementation; - } - - /** - * Creates a BrightnessCorrection that given {@code brightness}, corrects it to be - * {@code exp(scale * log(brightness) + translate)}. - * - * @param scale - * How much to scale the log brightness. - * @param translate - * How much to translate the log brightness. - * - * @return A BrightnessCorrection that given {@code brightness}, corrects it to be - * {@code exp(scale * log(brightness) + translate)}. - * - * @throws IllegalArgumentException - * - scale or translate are NaN. - */ - @NonNull - public static BrightnessCorrection createScaleAndTranslateLog(float scale, float translate) { - BrightnessCorrectionImplementation implementation = - new ScaleAndTranslateLog(scale, translate); - return new BrightnessCorrection(implementation); - } - - /** - * Applies the brightness correction to a given brightness. - * - * @param brightness - * The brightness. - * - * @return The corrected brightness. - */ - public float apply(float brightness) { - return mImplementation.apply(brightness); - } - - /** - * Returns a string representation. - * - * @return A string representation. - */ - public String toString() { - return mImplementation.toString(); - } - - public static final Creator<BrightnessCorrection> CREATOR = - new Creator<BrightnessCorrection>() { - public BrightnessCorrection createFromParcel(Parcel in) { - final int type = in.readInt(); - switch (type) { - case SCALE_AND_TRANSLATE_LOG: - return ScaleAndTranslateLog.readFromParcel(in); - } - return null; - } - - public BrightnessCorrection[] newArray(int size) { - return new BrightnessCorrection[size]; - } - }; - - @Override - public void writeToParcel(Parcel dest, int flags) { - mImplementation.writeToParcel(dest); - } - - @Override - public int describeContents() { - return 0; - } - - /** - * Writes the correction to an XML serializer. - * - * @param serializer - * The XML serializer. - * - * @hide - */ - public void saveToXml(XmlSerializer serializer) throws IOException { - mImplementation.saveToXml(serializer); - } - - /** - * Read a correction from an XML parser. - * - * @param parser - * The XML parser. - * - * @throws IOException - * The parser failed to read the XML file. - * @throws XmlPullParserException - * The parser failed to parse the XML file. - * - * @hide - */ - public static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException, - XmlPullParserException { - final int depth = parser.getDepth(); - while (XmlUtils.nextElementWithin(parser, depth)) { - if (TAG_SCALE_AND_TRANSLATE_LOG.equals(parser.getName())) { - return ScaleAndTranslateLog.loadFromXml(parser); - } - } - return null; - } - - private static float loadFloatFromXml(XmlPullParser parser, String attribute) { - final String string = parser.getAttributeValue(null, attribute); - try { - return Float.parseFloat(string); - } catch (NullPointerException | NumberFormatException e) { - return Float.NaN; - } - } - - private interface BrightnessCorrectionImplementation { - float apply(float brightness); - String toString(); - void writeToParcel(Parcel dest); - void saveToXml(XmlSerializer serializer) throws IOException; - // Package-private static methods: - // static BrightnessCorrection readFromParcel(Parcel in); - // static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException, - // XmlPullParserException; - } - - /** - * A BrightnessCorrection that given {@code brightness}, corrects it to be - * {@code exp(scale * log(brightness) + translate)}. - */ - private static class ScaleAndTranslateLog implements BrightnessCorrectionImplementation { - private static final float MIN_SCALE = 0.5f; - private static final float MAX_SCALE = 2.0f; - private static final float MIN_TRANSLATE = -0.6f; - private static final float MAX_TRANSLATE = 0.7f; - - private static final String ATTR_SCALE = "scale"; - private static final String ATTR_TRANSLATE = "translate"; - - private final float mScale; - private final float mTranslate; - - ScaleAndTranslateLog(float scale, float translate) { - if (Float.isNaN(scale) || Float.isNaN(translate)) { - throw new IllegalArgumentException("scale and translate must be numbers"); - } - mScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE); - mTranslate = MathUtils.constrain(translate, MIN_TRANSLATE, MAX_TRANSLATE); - } - - @Override - public float apply(float brightness) { - return MathUtils.exp(mScale * MathUtils.log(brightness) + mTranslate); - } - - @Override - public String toString() { - return "ScaleAndTranslateLog(" + mScale + ", " + mTranslate + ")"; - } - - @Override - public void writeToParcel(Parcel dest) { - dest.writeInt(SCALE_AND_TRANSLATE_LOG); - dest.writeFloat(mScale); - dest.writeFloat(mTranslate); - } - - @Override - public void saveToXml(XmlSerializer serializer) throws IOException { - serializer.startTag(null, TAG_SCALE_AND_TRANSLATE_LOG); - serializer.attribute(null, ATTR_SCALE, Float.toString(mScale)); - serializer.attribute(null, ATTR_TRANSLATE, Float.toString(mTranslate)); - serializer.endTag(null, TAG_SCALE_AND_TRANSLATE_LOG); - } - - static BrightnessCorrection readFromParcel(Parcel in) { - float scale = in.readFloat(); - float translate = in.readFloat(); - return BrightnessCorrection.createScaleAndTranslateLog(scale, translate); - } - - static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException, - XmlPullParserException { - final float scale = loadFloatFromXml(parser, ATTR_SCALE); - final float translate = loadFloatFromXml(parser, ATTR_TRANSLATE); - return BrightnessCorrection.createScaleAndTranslateLog(scale, translate); - } - } -} diff --git a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java index 9bebbd22c38c..d382eb9310d9 100644 --- a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java +++ b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java @@ -17,6 +17,7 @@ package android.hardware.hdmi; import android.annotation.Nullable; import android.os.Handler; +import android.os.Looper; import android.os.RemoteException; import com.android.internal.annotations.VisibleForTesting; @@ -52,7 +53,7 @@ public final class HdmiAudioSystemClient extends HdmiClient { @VisibleForTesting(visibility = Visibility.PACKAGE) public HdmiAudioSystemClient(IHdmiControlService service, @Nullable Handler handler) { super(service); - mHandler = handler == null ? new Handler() : handler; + mHandler = handler == null ? new Handler(Looper.getMainLooper()) : handler; } /** @hide */ diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index 72a6ffe3aac4..b520d2c14edc 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -388,6 +388,19 @@ public final class HdmiControlManager { } /** + * Gets whether the system is in system audio mode. + * + * @hide + */ + public boolean getSystemAudioMode() { + try { + return mService.getSystemAudioMode(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Listener used to get hotplug event from HDMI port. */ public interface HotplugEventListener { diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 877187053486..e55e0364f5d4 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -325,6 +325,7 @@ public final class NfcAdapter { // Guarded by NfcAdapter.class static boolean sIsInitialized = false; static boolean sHasNfcFeature; + static boolean sHasBeamFeature; // Final after first constructor, except for // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort @@ -372,7 +373,9 @@ public final class NfcAdapter { * A callback to be invoked when the system successfully delivers your {@link NdefMessage} * to another device. * @see #setOnNdefPushCompleteCallback + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public interface OnNdefPushCompleteCallback { /** * Called on successful NDEF push. @@ -395,7 +398,9 @@ public final class NfcAdapter { * content currently visible to the user. Alternatively, you can call {@link * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the * same data. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public interface CreateNdefMessageCallback { /** * Called to provide a {@link NdefMessage} to push. @@ -421,7 +426,10 @@ public final class NfcAdapter { } - // TODO javadoc + /** + * @deprecated this feature is deprecated. + */ + @java.lang.Deprecated public interface CreateBeamUrisCallback { public Uri[] createBeamUris(NfcEvent event); } @@ -449,6 +457,25 @@ public final class NfcAdapter { public boolean onUnlockAttempted(Tag tag); } + /** + * Helper to check if this device has FEATURE_NFC_BEAM, but without using + * a context. + * Equivalent to + * context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_BEAM) + */ + private static boolean hasBeamFeature() { + IPackageManager pm = ActivityThread.getPackageManager(); + if (pm == null) { + Log.e(TAG, "Cannot get package manager, assuming no Android Beam feature"); + return false; + } + try { + return pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM, 0); + } catch (RemoteException e) { + Log.e(TAG, "Package manager query failed, assuming no Android Beam feature", e); + return false; + } + } /** * Helper to check if this device has FEATURE_NFC, but without using @@ -528,6 +555,7 @@ public final class NfcAdapter { public static synchronized NfcAdapter getNfcAdapter(Context context) { if (!sIsInitialized) { sHasNfcFeature = hasNfcFeature(); + sHasBeamFeature = hasBeamFeature(); boolean hasHceFeature = hasNfcHceFeature(); /* is this device meant to have NFC */ if (!sHasNfcFeature && !hasHceFeature) { @@ -953,12 +981,17 @@ public final class NfcAdapter { * @param uris an array of Uri(s) to push over Android Beam * @param activity activity for which the Uri(s) will be pushed * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public void setBeamPushUris(Uri[] uris, Activity activity) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } if (activity == null) { throw new NullPointerException("activity cannot be null"); @@ -1035,12 +1068,17 @@ public final class NfcAdapter { * @param callback callback, or null to disable * @param activity activity for which the Uri(s) will be pushed * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } if (activity == null) { throw new NullPointerException("activity cannot be null"); @@ -1119,13 +1157,18 @@ public final class NfcAdapter { * to only register one at a time, and to do so in that activity's * {@link Activity#onCreate} * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public void setNdefPushMessage(NdefMessage message, Activity activity, Activity ... activities) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } int targetSdkVersion = getSdkVersion(); try { @@ -1232,13 +1275,18 @@ public final class NfcAdapter { * to only register one at a time, and to do so in that activity's * {@link Activity#onCreate} * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity, Activity ... activities) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } int targetSdkVersion = getSdkVersion(); try { @@ -1313,13 +1361,18 @@ public final class NfcAdapter { * to only register one at a time, and to do so in that activity's * {@link Activity#onCreate} * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback, Activity activity, Activity ... activities) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } int targetSdkVersion = getSdkVersion(); try { @@ -1524,12 +1577,17 @@ public final class NfcAdapter { * @param activity the current foreground Activity that has registered data to share * @return whether the Beam animation was successfully invoked * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated public boolean invokeBeam(Activity activity) { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return false; + } } if (activity == null) { throw new NullPointerException("activity may not be null."); @@ -1593,6 +1651,9 @@ public final class NfcAdapter { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } if (activity == null || message == null) { throw new NullPointerException(); @@ -1627,6 +1688,9 @@ public final class NfcAdapter { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return; + } } if (activity == null) { throw new NullPointerException(); @@ -1700,12 +1764,18 @@ public final class NfcAdapter { * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS * @return true if NDEF Push feature is enabled * @throws UnsupportedOperationException if FEATURE_NFC is unavailable. + * @deprecated this feature is deprecated. */ + @java.lang.Deprecated + public boolean isNdefPushEnabled() { synchronized (NfcAdapter.class) { if (!sHasNfcFeature) { throw new UnsupportedOperationException(); } + if (!sHasBeamFeature) { + return false; + } } try { return sService.isNdefPushEnabled(); diff --git a/core/java/android/os/AppZygote.java b/core/java/android/os/AppZygote.java new file mode 100644 index 000000000000..40cbaf75c02d --- /dev/null +++ b/core/java/android/os/AppZygote.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.content.pm.ApplicationInfo; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +/** + * AppZygote is responsible for interfacing with an application-specific zygote. + * + * Application zygotes can pre-load app-specific code and data, and this interface can + * be used to spawn isolated services from such an application zygote. + * + * Note that we'll have only one instance of this per application / uid combination. + * + * @hide + */ +public class AppZygote { + private static final String LOG_TAG = "AppZygote"; + + private final int mZygoteUid; + + private final Object mLock = new Object(); + + /** + * Instance that maintains the socket connection to the zygote. This is {@code null} if the + * zygote is not running or is not connected. + */ + @GuardedBy("mLock") + private ChildZygoteProcess mZygote; + + private final ApplicationInfo mAppInfo; + + public AppZygote(ApplicationInfo appInfo, int zygoteUid) { + mAppInfo = appInfo; + mZygoteUid = zygoteUid; + } + + /** + * Returns the zygote process associated with this app zygote. + * Creates the process if it's not already running. + */ + public ChildZygoteProcess getProcess() { + synchronized (mLock) { + if (mZygote != null) return mZygote; + + connectToZygoteIfNeededLocked(); + return mZygote; + } + } + + /** + * Stops the Zygote and kills the zygote process. + */ + public void stopZygote() { + synchronized (mLock) { + stopZygoteLocked(); + } + } + + public ApplicationInfo getAppInfo() { + return mAppInfo; + } + + @GuardedBy("mLock") + private void stopZygoteLocked() { + if (mZygote != null) { + // Close the connection and kill the zygote process. This will not cause + // child processes to be killed by itself. + mZygote.close(); + Process.killProcess(mZygote.getPid()); + mZygote = null; + } + } + + @GuardedBy("mLock") + private void connectToZygoteIfNeededLocked() { + String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi : + Build.SUPPORTED_ABIS[0]; + try { + mZygote = Process.zygoteProcess.startChildZygote( + "com.android.internal.os.AppZygoteInit", + mAppInfo.processName + "_zygote", + mZygoteUid, + mZygoteUid, + null, // gids + 0, // runtimeFlags + "app_zygote", // seInfo + abi, // abi + abi, // acceptedAbiList + null); // instructionSet + + ZygoteProcess.waitForConnectionToZygote(mZygote.getPrimarySocketAddress()); + // preload application code in the zygote + Log.i(LOG_TAG, "Starting application preload."); + mZygote.preloadApp(mAppInfo, abi); + Log.i(LOG_TAG, "Application preload done."); + } catch (Exception e) { + Log.e(LOG_TAG, "Error connecting to app zygote", e); + stopZygoteLocked(); + } + } +} diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 938b23ca733f..ee56e3d0ad16 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -205,6 +205,24 @@ public class Process { public static final int LAST_APPLICATION_UID = 19999; /** + * First uid used for fully isolated sandboxed processes spawned from an app zygote + * @hide + */ + public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; + + /** + * Number of UIDs we allocate per application zygote + * @hide + */ + public static final int NUM_UIDS_PER_APP_ZYGOTE = 100; + + /** + * Last uid used for fully isolated sandboxed processes spawned from an app zygote + * @hide + */ + public static final int LAST_APP_ZYGOTE_ISOLATED_UID = 98999; + + /** * First uid used for fully isolated sandboxed processes (with no permissions of their own) * @hide */ @@ -650,7 +668,8 @@ public class Process { /** {@hide} */ public static final boolean isIsolated(int uid) { uid = UserHandle.getAppId(uid); - return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID; + return (uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID) + || (uid >= FIRST_APP_ZYGOTE_ISOLATED_UID && uid <= LAST_APP_ZYGOTE_ISOLATED_UID); } /** diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index f8feb7b4a693..ad8a4d5645bc 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -138,8 +138,7 @@ public final class UserHandle implements Parcelable { */ public static boolean isIsolated(int uid) { if (uid > 0) { - final int appId = getAppId(uid); - return appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID; + return Process.isIsolated(uid); } else { return false; } @@ -294,9 +293,14 @@ public final class UserHandle implements Parcelable { sb.append('u'); sb.append(getUserId(uid)); final int appId = getAppId(uid); - if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) { - sb.append('i'); - sb.append(appId - Process.FIRST_ISOLATED_UID); + if (isIsolated(appId)) { + if (appId > Process.FIRST_ISOLATED_UID) { + sb.append('i'); + sb.append(appId - Process.FIRST_ISOLATED_UID); + } else { + sb.append("ai"); + sb.append(appId - Process.FIRST_APP_ZYGOTE_ISOLATED_UID); + } } else if (appId >= Process.FIRST_APPLICATION_UID) { sb.append('a'); sb.append(appId - Process.FIRST_APPLICATION_UID); @@ -330,9 +334,14 @@ public final class UserHandle implements Parcelable { pw.print('u'); pw.print(getUserId(uid)); final int appId = getAppId(uid); - if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) { - pw.print('i'); - pw.print(appId - Process.FIRST_ISOLATED_UID); + if (isIsolated(appId)) { + if (appId > Process.FIRST_ISOLATED_UID) { + pw.print('i'); + pw.print(appId - Process.FIRST_ISOLATED_UID); + } else { + pw.print("ai"); + pw.print(appId - Process.FIRST_APP_ZYGOTE_ISOLATED_UID); + } } else if (appId >= Process.FIRST_APPLICATION_UID) { pw.print('a'); pw.print(appId - Process.FIRST_APPLICATION_UID); diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index f136cd6699a7..251c5eebadc4 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -18,6 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ApplicationInfo; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.util.Log; @@ -34,6 +35,7 @@ import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -673,6 +675,36 @@ public class ZygoteProcess { } /** + * Instructs the zygote to pre-load the application code for the given Application. + * Only the app zygote supports this function. + * TODO preloadPackageForAbi() can probably be removed and the callers an use this instead. + */ + public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx, + IOException { + synchronized (mLock) { + ZygoteState state = openZygoteSocketIfNeeded(abi); + state.writer.write("2"); + state.writer.newLine(); + + state.writer.write("--preload-app"); + state.writer.newLine(); + + // Zygote args needs to be strings, so in order to pass ApplicationInfo, + // write it to a Parcel, and base64 the raw Parcel bytes to the other side. + Parcel parcel = Parcel.obtain(); + appInfo.writeToParcel(parcel, 0 /* flags */); + String encodedParcelData = Base64.getEncoder().encodeToString(parcel.marshall()); + parcel.recycle(); + state.writer.write(encodedParcelData); + state.writer.newLine(); + + state.writer.flush(); + + return (state.inputStream.readInt() == 0); + } + } + + /** * Instructs the zygote to pre-load the classes and native libraries at the given paths * for the specified abi. Not all zygotes support this function. */ @@ -763,6 +795,20 @@ public class ZygoteProcess { * secondary zygotes that inherit data from the zygote that this object * communicates with. This returns a new ZygoteProcess representing a connection * to the newly created zygote. Throws an exception if the zygote cannot be started. + * + * @param processClass The class to use as the child zygote's main entry + * point. + * @param niceName A more readable name to use for the process. + * @param uid The user-id under which the child zygote will run. + * @param gid The group-id under which the child zygote will run. + * @param gids Additional group-ids associated with the child zygote process. + * @param runtimeFlags Additional flags. + * @param seInfo null-ok SELinux information for the child zygote process. + * @param abi non-null the ABI of the child zygote + * @param acceptedAbiList ABIs this child zygote will accept connections for; this + * may be different from <code>abi</code> in case the children + * spawned from this Zygote only communicate using ABI-safe methods. + * @param instructionSet null-ok the instruction set to use. */ public ChildZygoteProcess startChildZygote(final String processClass, final String niceName, @@ -770,12 +816,14 @@ public class ZygoteProcess { int runtimeFlags, String seInfo, String abi, + String acceptedAbiList, String instructionSet) { // Create an unguessable address in the global abstract namespace. final LocalSocketAddress serverAddress = new LocalSocketAddress( processClass + "/" + UUID.randomUUID().toString()); - final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName()}; + final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName(), + Zygote.CHILD_ZYGOTE_ABI_LIST_ARG + acceptedAbiList}; Process.ProcessStartResult result; try { diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 9594a713a506..735f4f253594 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1540,6 +1540,7 @@ public class StorageManager { } /** {@hide} */ + @SystemApi @TestApi public static boolean hasIsolatedStorage() { // Prefer to use snapshot for current boot when available diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java index e5fd29cc09b1..b348da45e2d6 100644 --- a/core/java/android/provider/Downloads.java +++ b/core/java/android/provider/Downloads.java @@ -409,6 +409,15 @@ public final class Downloads { public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri"; /** + * Similar to {@link #COLUMN_MEDIAPROVIDER_URI}, except this cannot be updated/queried + * by apps and will be the source of truth when updating/deleting download entries in + * MediaProvider database. + * + * <P>Type: TEXT</P> + */ + public static final String COLUMN_MEDIASTORE_URI = "mediastore_uri"; + + /** * The column that is used to remember whether the media scanner was invoked. * It can take the values: null or 0(not scanned), 1(scanned), 2 (not scannable). * <P>Type: TEXT</P> diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index c4e2b1299fc2..cdbc9790c952 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -17,6 +17,7 @@ package android.provider; import android.annotation.BytesLong; +import android.annotation.DurationMillisLong; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; @@ -55,6 +56,7 @@ import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; import android.service.media.CameraPrewarmService; import android.text.TextUtils; +import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; @@ -131,6 +133,8 @@ public final class MediaStore { /** {@hide} */ public static final String PARAM_INCLUDE_PENDING = "includePending"; /** {@hide} */ + public static final String PARAM_INCLUDE_TRASHED = "includeTrashed"; + /** {@hide} */ public static final String PARAM_PROGRESS = "progress"; /** {@hide} */ public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal"; @@ -485,12 +489,29 @@ public final class MediaStore { * By default no pending items are returned. * * @see MediaColumns#IS_PENDING + * @see MediaStore#setIncludePending(Uri) + * @see MediaStore#createPending(Context, PendingParams) */ public static @NonNull Uri setIncludePending(@NonNull Uri uri) { return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_PENDING, "1").build(); } /** + * Update the given {@link Uri} to also include any trashed media items from + * calls such as + * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. + * By default no trashed items are returned. + * + * @see MediaColumns#IS_TRASHED + * @see MediaStore#setIncludeTrashed(Uri) + * @see MediaStore#trash(Context, Uri) + * @see MediaStore#untrash(Context, Uri) + */ + public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) { + return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build(); + } + + /** * Update the given {@link Uri} to indicate that the caller requires the * original file contents when calling * {@link ContentResolver#openFileDescriptor(Uri, String)}. @@ -516,6 +537,9 @@ public final class MediaStore { * * @return token which can be passed to {@link #openPending(Context, Uri)} * to work with this pending item. + * @see MediaColumns#IS_PENDING + * @see MediaStore#setIncludePending(Uri) + * @see MediaStore#createPending(Context, PendingParams) */ public static @NonNull Uri createPending(@NonNull Context context, @NonNull PendingParams params) { @@ -572,6 +596,8 @@ public final class MediaStore { this.insertValues.put(MediaColumns.DATE_ADDED, now); this.insertValues.put(MediaColumns.DATE_MODIFIED, now); this.insertValues.put(MediaColumns.IS_PENDING, 1); + this.insertValues.put(MediaColumns.DATE_EXPIRES, + (System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000); } /** @@ -696,6 +722,7 @@ public final class MediaStore { public @NonNull Uri publish() { final ContentValues values = new ContentValues(); values.put(MediaColumns.IS_PENDING, 0); + values.putNull(MediaColumns.DATE_EXPIRES); mContext.getContentResolver().update(mUri, values, null, null); return mUri; } @@ -717,6 +744,67 @@ public final class MediaStore { } /** + * Mark the given item as being "trashed", meaning it should be deleted at + * some point in the future. This is a more gentle operation than simply + * calling {@link ContentResolver#delete(Uri, String, String[])}, which + * would take effect immediately. + * <p> + * This method preserves trashed items for at least 48 hours before erasing + * them, giving the user a chance to untrash the item. + * + * @see MediaColumns#IS_TRASHED + * @see MediaStore#setIncludeTrashed(Uri) + * @see MediaStore#trash(Context, Uri) + * @see MediaStore#untrash(Context, Uri) + */ + public static void trash(@NonNull Context context, @NonNull Uri uri) { + trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS); + } + + /** + * Mark the given item as being "trashed", meaning it should be deleted at + * some point in the future. This is a more gentle operation than simply + * calling {@link ContentResolver#delete(Uri, String, String[])}, which + * would take effect immediately. + * <p> + * This method preserves trashed items for at least the given timeout before + * erasing them, giving the user a chance to untrash the item. + * + * @see MediaColumns#IS_TRASHED + * @see MediaStore#setIncludeTrashed(Uri) + * @see MediaStore#trash(Context, Uri) + * @see MediaStore#untrash(Context, Uri) + */ + public static void trash(@NonNull Context context, @NonNull Uri uri, + @DurationMillisLong long timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException(); + } + + final ContentValues values = new ContentValues(); + values.put(MediaColumns.IS_TRASHED, 1); + values.put(MediaColumns.DATE_EXPIRES, + (System.currentTimeMillis() + timeoutMillis) / 1000); + context.getContentResolver().update(uri, values, null, null); + } + + /** + * Mark the given item as being "untrashed", meaning it should no longer be + * deleted as previously requested through {@link #trash(Context, Uri)}. + * + * @see MediaColumns#IS_TRASHED + * @see MediaStore#setIncludeTrashed(Uri) + * @see MediaStore#trash(Context, Uri) + * @see MediaStore#untrash(Context, Uri) + */ + public static void untrash(@NonNull Context context, @NonNull Uri uri) { + final ContentValues values = new ContentValues(); + values.put(MediaColumns.IS_TRASHED, 0); + values.putNull(MediaColumns.DATE_EXPIRES); + context.getContentResolver().update(uri, values, null, null); + } + + /** * Common fields for most MediaProvider tables */ public interface MediaColumns extends BaseColumns { @@ -821,12 +909,34 @@ public final class MediaStore { * <p> * Type: BOOLEAN * + * @see MediaColumns#IS_PENDING + * @see MediaStore#setIncludePending(Uri) * @see MediaStore#createPending(Context, PendingParams) - * @see MediaStore#PARAM_INCLUDE_PENDING */ public static final String IS_PENDING = "is_pending"; /** + * Flag indicating if a media item is trashed. + * <p> + * Type: BOOLEAN + * + * @see MediaColumns#IS_TRASHED + * @see MediaStore#setIncludeTrashed(Uri) + * @see MediaStore#trash(Context, Uri) + * @see MediaStore#untrash(Context, Uri) + */ + public static final String IS_TRASHED = "is_trashed"; + + /** + * The time the file should be considered expired. Units are seconds + * since 1970. Typically only meaningful in the context of + * {@link #IS_PENDING} or {@link #IS_TRASHED}. + * <p> + * Type: INTEGER + */ + public static final String DATE_EXPIRES = "date_expires"; + + /** * The width of the image/video in pixels. */ public static final String WIDTH = "width"; @@ -915,6 +1025,11 @@ public final class MediaStore { return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("dir").build(); } + /** @hide */ + public static final Uri getContentUriForPath(String path) { + return getContentUri(getVolumeNameForPath(path)); + } + /** * Fields for master table for all media files. * Table also contains MediaColumns._ID, DATA, SIZE and DATE_MODIFIED. @@ -1021,6 +1136,13 @@ public final class MediaStore { * Type: TEXT */ String REFERER_URI = "referer_uri"; + + /** + * The description of the download. + * <p> + * Type: Text + */ + String DESCRIPTION = "description"; } /** @@ -1251,18 +1373,32 @@ public final class MediaStore { public static final String MINI_THUMB_MAGIC = "mini_thumb_magic"; /** - * The bucket id of the image. This is a read-only property that - * is automatically computed from the DATA column. - * <P>Type: TEXT</P> + * The primary bucket ID of this media item. This can be useful to + * present the user a first-level clustering of related media items. + * This is a read-only column that is automatically computed. + * <p> + * Type: INTEGER */ public static final String BUCKET_ID = "bucket_id"; /** - * The bucket display name of the image. This is a read-only property that - * is automatically computed from the DATA column. - * <P>Type: TEXT</P> + * The primary bucket display name of this media item. This can be + * useful to present the user a first-level clustering of related + * media items. This is a read-only column that is automatically + * computed. + * <p> + * Type: TEXT */ public static final String BUCKET_DISPLAY_NAME = "bucket_display_name"; + + /** + * The secondary bucket ID of this media item. This can be useful to + * present the user a second-level clustering of related media + * items. This is a read-only column that is automatically computed. + * <p> + * Type: INTEGER + */ + public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id"; } public static final class Media implements ImageColumns { @@ -2500,20 +2636,34 @@ public final class MediaStore { public static final String MINI_THUMB_MAGIC = "mini_thumb_magic"; /** - * The bucket id of the video. This is a read-only property that - * is automatically computed from the DATA column. - * <P>Type: TEXT</P> + * The primary bucket ID of this media item. This can be useful to + * present the user a first-level clustering of related media items. + * This is a read-only column that is automatically computed. + * <p> + * Type: INTEGER */ public static final String BUCKET_ID = "bucket_id"; /** - * The bucket display name of the video. This is a read-only property that - * is automatically computed from the DATA column. - * <P>Type: TEXT</P> + * The primary bucket display name of this media item. This can be + * useful to present the user a first-level clustering of related + * media items. This is a read-only column that is automatically + * computed. + * <p> + * Type: TEXT */ public static final String BUCKET_DISPLAY_NAME = "bucket_display_name"; /** + * The secondary bucket ID of this media item. This can be useful to + * present the user a second-level clustering of related media + * items. This is a read-only column that is automatically computed. + * <p> + * Type: INTEGER + */ + public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id"; + + /** * The bookmark for the video. Time in ms. Represents the location in the video that the * video should start playing at the next time it is opened. If the value is null or * out of the range 0..DURATION-1 then the video should start playing from the diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index a011d677fc6a..9079502fa6b2 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -56,6 +56,7 @@ import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.InsetsState; import android.view.MotionEvent; +import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; @@ -217,6 +218,8 @@ public abstract class WallpaperService extends Service { private Context mDisplayContext; private int mDisplayState; + SurfaceControl mSurfaceControl = new SurfaceControl(); + final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { { mRequestedFormat = PixelFormat.RGBX_8888; @@ -843,8 +846,12 @@ public abstract class WallpaperService extends Service { mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, View.VISIBLE, 0, -1, mWinFrame, mOverscanInsets, mContentInsets, mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame, - mDisplayCutout, mMergedConfiguration, mSurfaceHolder.mSurface, + mDisplayCutout, mMergedConfiguration, mSurfaceControl, mInsetsState); + if (mSurfaceControl.isValid()) { + mSurfaceHolder.mSurface.copyFrom(mSurfaceControl); + mSurfaceControl.release(); + } if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface + ", frame=" + mWinFrame); diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java index 9f7560c79166..54cfc00cb5b3 100644 --- a/core/java/android/view/AccessibilityIterators.java +++ b/core/java/android/view/AccessibilityIterators.java @@ -147,6 +147,9 @@ public final class AccessibilityIterators { @Override public void onConfigurationChanged(Configuration globalConfig) { final Locale locale = globalConfig.getLocales().get(0); + if (locale == null) { + return; + } if (!mLocale.equals(locale)) { mLocale = locale; onLocaleChanged(locale); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index d1115c7b4d1d..658f06ad21f9 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -99,7 +99,7 @@ interface IWindowSession { out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets, out Rect outOutsets, out Rect outBackdropFrame, out DisplayCutout.ParcelableWrapper displayCutout, - out MergedConfiguration outMergedConfiguration, out Surface outSurface, + out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, out InsetsState insetsState); /* diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 3f8f882a869f..885b3e94c593 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -250,7 +250,7 @@ public class InsetsState implements Parcelable { } } - static String typeToString(int type) { + public static String typeToString(int type) { switch (type) { case TYPE_TOP_BAR: return "TYPE_TOP_BAR"; diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index be81c06de1af..ffd4156b5bfd 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -784,24 +784,8 @@ public abstract class LayoutInflater { ta.recycle(); } - if (name.equals(TAG_1995)) { - // Let's party like it's 1995! - return new BlinkLayout(context, attrs); - } - try { - View view; - if (mFactory2 != null) { - view = mFactory2.onCreateView(parent, name, context, attrs); - } else if (mFactory != null) { - view = mFactory.onCreateView(name, context, attrs); - } else { - view = null; - } - - if (view == null && mPrivateFactory != null) { - view = mPrivateFactory.onCreateView(parent, name, context, attrs); - } + View view = tryCreateView(parent, name, context, attrs); if (view == null) { final Object lastContext = mConstructorArgs[0]; @@ -836,6 +820,48 @@ public abstract class LayoutInflater { } /** + * Tries to create a view from a tag name using the supplied attribute set. + * + * This method gives the factory provided by {@link LayoutInflater#setFactory} and + * {@link LayoutInflater#setFactory2} a chance to create a view. However, it does not apply all + * of the general view creation logic, and thus may return {@code null} for some tags. This + * method is used by {@link LayoutInflater#inflate} in creating {@code View} objects. + * + * @hide for use by precompiled layouts. + * + * @param parent the parent view, used to inflate layout params + * @param name the name of the XML tag used to define the view + * @param context the inflation context for the view, typically the + * {@code parent} or base layout inflater context + * @param attrs the attribute set for the XML tag used to define the view + */ + @UnsupportedAppUsage(trackingBug = 122360734) + @Nullable + public final View tryCreateView(@Nullable View parent, @NonNull String name, + @NonNull Context context, + @NonNull AttributeSet attrs) { + if (name.equals(TAG_1995)) { + // Let's party like it's 1995! + return new BlinkLayout(context, attrs); + } + + View view; + if (mFactory2 != null) { + view = mFactory2.onCreateView(parent, name, context, attrs); + } else if (mFactory != null) { + view = mFactory.onCreateView(name, context, attrs); + } else { + view = null; + } + + if (view == null && mPrivateFactory != null) { + view = mPrivateFactory.onCreateView(parent, name, context, attrs); + } + + return view; + } + + /** * Recursive method used to inflate internal (non-root) children. This * method calls through to {@link #rInflate} using the parent context as * the inflation context. diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 1a708e8e30ec..0b6beba06555 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -67,6 +67,7 @@ public class SurfaceControl implements Parcelable { int w, int h, int format, int flags, long parentObject, int windowType, int ownerUid) throws OutOfResourcesException; private static native long nativeReadFromParcel(Parcel in); + private static native long nativeCopyFromSurfaceControl(long nativeObject); private static native void nativeWriteToParcel(long nativeObject, Parcel out); private static native void nativeRelease(long nativeObject); private static native void nativeDestroy(long nativeObject); @@ -169,7 +170,7 @@ public class SurfaceControl implements Parcelable { IBinder toToken); private final CloseGuard mCloseGuard = CloseGuard.get(); - private final String mName; + private String mName; long mNativeObject; // package visibility only for Surface.java access // TODO: Move this to native. @@ -359,6 +360,13 @@ public class SurfaceControl implements Parcelable { */ public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; + public void copyFrom(SurfaceControl other) { + mName = other.mName; + mWidth = other.mWidth; + mHeight = other.mHeight; + mNativeObject = nativeCopyFromSurfaceControl(other.mNativeObject); + } + /** * Builder class for {@link SurfaceControl} objects. */ @@ -660,14 +668,29 @@ public class SurfaceControl implements Parcelable { } private SurfaceControl(Parcel in) { + readFromParcel(in); + mCloseGuard.open("release"); + } + + public SurfaceControl() { + mCloseGuard.open("release"); + } + + public void readFromParcel(Parcel in) { + if (in == null) { + throw new IllegalArgumentException("source must not be null"); + } + mName = in.readString(); mWidth = in.readInt(); mHeight = in.readInt(); - mNativeObject = nativeReadFromParcel(in); - if (mNativeObject == 0) { - throw new IllegalArgumentException("Couldn't read SurfaceControl from parcel=" + in); + + release(); + if (in.readInt() != 0) { + mNativeObject = nativeReadFromParcel(in); + } else { + mNativeObject = 0; } - mCloseGuard.open("release"); } @Override @@ -680,7 +703,16 @@ public class SurfaceControl implements Parcelable { dest.writeString(mName); dest.writeInt(mWidth); dest.writeInt(mHeight); + if (mNativeObject == 0) { + dest.writeInt(0); + } else { + dest.writeInt(1); + } nativeWriteToParcel(mNativeObject, dest); + + if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { + release(); + } } /** @@ -763,6 +795,10 @@ public class SurfaceControl implements Parcelable { "mNativeObject is null. Have you called release() already?"); } + public boolean isValid() { + return mNativeObject != 0; + } + /* * set surface parameters. * needs to be inside open/closeTransaction block diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index a4fa12a57e93..361ac932758e 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -30,7 +30,6 @@ public final class SurfaceSession { private long mNativeClient; // SurfaceComposerClient* private static native long nativeCreate(); - private static native long nativeCreateScoped(long surfacePtr); private static native void nativeDestroy(long ptr); private static native void nativeKill(long ptr); @@ -40,15 +39,6 @@ public final class SurfaceSession { mNativeClient = nativeCreate(); } - public SurfaceSession(Surface root) { - synchronized (root.mLock) { - if (root.mNativeObject == 0) { - throw new IllegalStateException("Surface is not initialized or has been released"); - } - mNativeClient = nativeCreateScoped(root.mNativeObject); - } - } - /* no user serviceable parts here ... */ @Override protected void finalize() throws Throwable { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index a0af83d17abd..61fb00d3fe59 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -547,7 +547,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (creating) { viewRoot.createBoundsSurface(mSubLayer); - mSurfaceSession = new SurfaceSession(viewRoot.mBoundsSurface); + mSurfaceSession = new SurfaceSession(); mDeferredDestroySurfaceControl = mSurfaceControl; updateOpaqueFlag(); @@ -559,6 +559,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb new SurfaceControl.Builder(mSurfaceSession) .setBufferSize(mSurfaceWidth, mSurfaceHeight) .setFormat(mFormat) + .setParent(viewRoot.getSurfaceControl()) .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null) { return; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6b07efc0b448..4504887f265b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -25053,9 +25053,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } final ViewRootImpl root = mAttachInfo.mViewRootImpl; - final SurfaceSession session = new SurfaceSession(root.mSurface); + final SurfaceSession session = new SurfaceSession(); final SurfaceControl surfaceControl = new SurfaceControl.Builder(session) .setName("drag surface") + .setParent(root.getSurfaceControl()) .setBufferSize(shadowSize.x, shadowSize.y) .setFormat(PixelFormat.TRANSLUCENT) .build(); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3f7a5127339d..c0b428359efc 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -432,6 +432,7 @@ public final class ViewRootImpl implements ViewParent, // Surface can never be reassigned or cleared (use Surface.clear()). @UnsupportedAppUsage public final Surface mSurface = new Surface(); + private final SurfaceControl mSurfaceControl = new SurfaceControl(); /** * Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds @@ -1526,7 +1527,7 @@ public final class ViewRootImpl implements ViewParent, */ public void createBoundsSurface(int zOrderLayer) { if (mSurfaceSession == null) { - mSurfaceSession = new SurfaceSession(mSurface); + mSurfaceSession = new SurfaceSession(); } if (mBoundsSurfaceControl != null && mBoundsSurface.isValid()) { return; // surface control for bounds surface already exists. @@ -1534,6 +1535,7 @@ public final class ViewRootImpl implements ViewParent, mBoundsSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) .setName("Bounds for - " + getTitle().toString()) + .setParent(mSurfaceControl) .build(); setBoundsSurfaceCrop(); @@ -1567,6 +1569,8 @@ public final class ViewRootImpl implements ViewParent, private void destroySurface() { mSurface.release(); + mSurfaceControl.release(); + mSurfaceSession = null; if (mBoundsSurfaceControl != null) { @@ -6801,7 +6805,12 @@ public final class ViewRootImpl implements ViewParent, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout, - mPendingMergedConfiguration, mSurface, mTempInsets); + mPendingMergedConfiguration, mSurfaceControl, mTempInsets); + if (mSurfaceControl.isValid()) { + mSurface.copyFrom(mSurfaceControl); + } else { + destroySurface(); + } mPendingAlwaysConsumeNavBar = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; @@ -8483,6 +8492,10 @@ public final class ViewRootImpl implements ViewParent, mActivityRelaunched = true; } + public SurfaceControl getSurfaceControl() { + return mSurfaceControl; + } + /** * Class for managing the accessibility interaction connection * based on the global accessibility state. diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java index 49e11b8baf51..9f7aa6a2852a 100644 --- a/core/java/android/webkit/WebViewZygote.java +++ b/core/java/android/webkit/WebViewZygote.java @@ -159,6 +159,7 @@ public class WebViewZygote { 0, // runtimeFlags "webview_zygote", // seInfo sPackage.applicationInfo.primaryCpuAbi, // abi + TextUtils.join(",", Build.SUPPORTED_ABIS), null); // instructionSet // All the work below is usually done by LoadedApk, but the zygote can't talk to diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 7d027574198d..886718d192e0 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -271,7 +271,7 @@ public final class Magnifier { if (mWindow == null) { synchronized (mLock) { mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(), - mParentSurface.mSurface, mWindowWidth, mWindowHeight, + mParentSurface.mSurfaceControl, mWindowWidth, mWindowHeight, mWindowElevation, mWindowCornerRadius, mOverlay != null ? mOverlay : new ColorDrawable(Color.TRANSPARENT), Handler.getMain() /* draw the magnifier on the UI thread */, mLock, @@ -528,17 +528,20 @@ public final class Magnifier { final int surfaceHeight = viewRootImpl.getHeight() + surfaceInsets.top + surfaceInsets.bottom; validMainWindowSurface = - new SurfaceInfo(mainWindowSurface, surfaceWidth, surfaceHeight, true); + new SurfaceInfo(viewRootImpl.getSurfaceControl(), mainWindowSurface, + surfaceWidth, surfaceHeight, true); } } // Get the surface backing the magnified view, if it is a SurfaceView. SurfaceInfo validSurfaceViewSurface = SurfaceInfo.NULL; if (mView instanceof SurfaceView) { + final SurfaceControl sc = ((SurfaceView) mView).getSurfaceControl(); final SurfaceHolder surfaceHolder = ((SurfaceView) mView).getHolder(); final Surface surfaceViewSurface = surfaceHolder.getSurface(); - if (surfaceViewSurface != null && surfaceViewSurface.isValid()) { + + if (sc != null && sc.isValid()) { final Rect surfaceFrame = surfaceHolder.getSurfaceFrame(); - validSurfaceViewSurface = new SurfaceInfo(surfaceViewSurface, + validSurfaceViewSurface = new SurfaceInfo(sc, surfaceViewSurface, surfaceFrame.right, surfaceFrame.bottom, false); } } @@ -733,15 +736,18 @@ public final class Magnifier { * Contains a surface and metadata corresponding to it. */ private static class SurfaceInfo { - public static final SurfaceInfo NULL = new SurfaceInfo(null, 0, 0, false); + public static final SurfaceInfo NULL = new SurfaceInfo(null, null, 0, 0, false); private Surface mSurface; + private SurfaceControl mSurfaceControl; private int mWidth; private int mHeight; private boolean mIsMainWindowSurface; - SurfaceInfo(final Surface surface, final int width, final int height, + SurfaceInfo(final SurfaceControl surfaceControl, final Surface surface, + final int width, final int height, final boolean isMainWindowSurface) { + mSurfaceControl = surfaceControl; mSurface = surface; mWidth = width; mHeight = height; @@ -819,7 +825,7 @@ public final class Magnifier { private Bitmap mCurrentContent; InternalPopupWindow(final Context context, final Display display, - final Surface parentSurface, final int width, final int height, + final SurfaceControl parentSurfaceControl, final int width, final int height, final float elevation, final float cornerRadius, final Drawable overlay, final Handler handler, final Object lock, final Callback callback) { mDisplay = display; @@ -834,12 +840,13 @@ public final class Magnifier { // Setup the surface we will use for drawing the content and shadow. mSurfaceWidth = mContentWidth + 2 * mOffsetX; mSurfaceHeight = mContentHeight + 2 * mOffsetY; - mSurfaceSession = new SurfaceSession(parentSurface); + mSurfaceSession = new SurfaceSession(); mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) .setFormat(PixelFormat.TRANSLUCENT) .setBufferSize(mSurfaceWidth, mSurfaceHeight) .setName("magnifier surface") .setFlags(SurfaceControl.HIDDEN) + .setParent(parentSurfaceControl) .build(); mSurface = new Surface(); mSurface.copyFrom(mSurfaceControl); diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java index 96d3baf7cf0b..f61a03bccb78 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverComparator.java @@ -22,44 +22,36 @@ import android.app.usage.UsageStatsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; +import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; -import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; -import android.content.SharedPreferences; -import android.content.ServiceConnection; import android.metrics.LogMaker; -import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; -import android.os.storage.StorageManager; import android.os.UserHandle; -import android.service.resolver.IResolverRankerService; import android.service.resolver.IResolverRankerResult; +import android.service.resolver.IResolverRankerService; import android.service.resolver.ResolverRankerService; import android.service.resolver.ResolverTarget; -import android.text.TextUtils; -import android.util.ArrayMap; import android.util.Log; + import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import java.io.File; -import java.lang.InterruptedException; import java.text.Collator; import java.util.ArrayList; import java.util.Comparator; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Ranks and compares packages based on usage stats. @@ -90,6 +82,8 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { private final Collator mCollator; private final boolean mHttp; + // can be null if mHttp == false or current user has no default browser package + private final String mDefaultBrowserPackageName; private final PackageManager mPm; private final UsageStatsManager mUsm; private final Map<String, UsageStats> mStats; @@ -184,6 +178,10 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { getContentAnnotations(intent); mAction = intent.getAction(); mRankerServiceName = new ComponentName(mContext, this.getClass()); + + mDefaultBrowserPackageName = mHttp + ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId()) + : null; } // get annotations of content from intent. @@ -312,7 +310,14 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { if (mHttp) { // Special case: we want filters that match URI paths/schemes to be // ordered before others. This is for the case when opening URIs, - // to make native apps go above browsers. + // to make native apps go above browsers - except for 1 even more special case + // which is the default browser, as we want that to go above them all. + if (isDefaultBrowser(lhs)) { + return -1; + } + if (isDefaultBrowser(rhs)) { + return 1; + } final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match); final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match); if (lhsSpecific != rhsSpecific) { @@ -419,6 +424,20 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { } } + private boolean isDefaultBrowser(ResolveInfo ri) { + // It makes sense to prefer the default browser + // only if the targeted user is the current user + if (ri.targetUserId != UserHandle.USER_CURRENT) { + return false; + } + + if (ri.activityInfo.packageName != null + && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) { + return true; + } + return false; + } + // records metrics for evaluation. private void logMetrics(int selectedPos) { if (mRankerServiceName != null) { diff --git a/core/java/com/android/internal/os/AppZygoteInit.java b/core/java/com/android/internal/os/AppZygoteInit.java new file mode 100644 index 000000000000..afe6dade62ac --- /dev/null +++ b/core/java/com/android/internal/os/AppZygoteInit.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import android.app.LoadedApk; +import android.content.pm.ApplicationInfo; +import android.net.LocalSocket; +import android.util.Log; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Startup class for an Application zygote process. + * + * See {@link ZygoteInit} for generic zygote startup documentation. + * + * @hide + */ +class AppZygoteInit { + public static final String TAG = "AppZygoteInit"; + + private static ZygoteServer sServer; + + private static class AppZygoteServer extends ZygoteServer { + @Override + protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList) + throws IOException { + return new AppZygoteConnection(socket, abiList); + } + } + + private static class AppZygoteConnection extends ZygoteConnection { + AppZygoteConnection(LocalSocket socket, String abiList) throws IOException { + super(socket, abiList); + } + + @Override + protected void preload() { + // Nothing to preload by default. + } + + @Override + protected boolean isPreloadComplete() { + // App zygotes don't preload any classes or resources or defaults, all of their + // preloading is package specific. + return true; + } + + @Override + protected boolean canPreloadApp() { + return true; + } + + @Override + protected void handlePreloadApp(ApplicationInfo appInfo) { + Log.i(TAG, "Beginning application preload for " + appInfo.packageName); + LoadedApk loadedApk = new LoadedApk(null, appInfo, null, null, false, true, false); + ClassLoader loader = loadedApk.getClassLoader(); + Class<?> cl; + Method m; + try { + cl = Class.forName(appInfo.packageName + ".ZygotePreload", true, loader); + m = cl.getMethod("doPreload"); + m.setAccessible(true); + m.invoke(null); + } catch (ClassNotFoundException e) { + // Don't treat this as an error since an app may not want to do any preloads + Log.w(TAG, "No ZygotePreload class found for " + appInfo.packageName); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Log.e(TAG, "AppZygote application preload failed for " + + appInfo.packageName, e); + } + try { + DataOutputStream socketOut = getSocketOutputStream(); + socketOut.writeInt(loader != null ? 1 : 0); + } catch (IOException e) { + throw new IllegalStateException("Error writing to command socket", e); + } + + Log.i(TAG, "Application preload done"); + } + } + + public static void main(String[] argv) { + AppZygoteServer server = new AppZygoteServer(); + ChildZygoteInit.runZygoteServer(server, argv); + } +} diff --git a/core/java/com/android/internal/os/ChildZygoteInit.java b/core/java/com/android/internal/os/ChildZygoteInit.java new file mode 100644 index 000000000000..f90cd0224596 --- /dev/null +++ b/core/java/com/android/internal/os/ChildZygoteInit.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.os; + +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; + +/** + * ChildZygoteInit is shared by both the Application and WebView zygote to initialize + * and run a (child) Zygote server. + * + * @hide + */ +public class ChildZygoteInit { + private static final String TAG = "ChildZygoteInit"; + + static String parseSocketNameFromArgs(String[] argv) { + for (String arg : argv) { + if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) { + return arg.substring(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG.length()); + } + } + + return null; + } + + static String parseAbiListFromArgs(String[] argv) { + for (String arg : argv) { + if (arg.startsWith(Zygote.CHILD_ZYGOTE_ABI_LIST_ARG)) { + return arg.substring(Zygote.CHILD_ZYGOTE_ABI_LIST_ARG.length()); + } + } + + return null; + } + + /** + * Starts a ZygoteServer and listens for requests + * + * @param server An instance of a ZygoteServer to listen on + * @param args Passed in arguments for this ZygoteServer + */ + static void runZygoteServer(ZygoteServer server, String[] args) { + String socketName = parseSocketNameFromArgs(args); + if (socketName == null) { + throw new NullPointerException("No socketName specified"); + } + + String abiList = parseAbiListFromArgs(args); + if (abiList == null) { + throw new NullPointerException("No abiList specified"); + } + + try { + Os.prctl(OsConstants.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + } catch (ErrnoException ex) { + throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); + } + + final Runnable caller; + try { + server.registerServerSocketAtAbstractName(socketName); + + // Add the abstract socket to the FD whitelist so that the native zygote code + // can properly detach it after forking. + Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName); + + // The select loop returns early in the child process after a fork and + // loops forever in the zygote. + caller = server.runSelectLoop(abiList); + } catch (RuntimeException e) { + Log.e(TAG, "Fatal exception:", e); + throw e; + } finally { + server.closeServerSocket(); + } + + // We're in the child process and have exited the select loop. Proceed to execute the + // command. + if (caller != null) { + caller.run(); + } + } +} diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java index dc660a452c3b..a319d83b077d 100644 --- a/core/java/com/android/internal/os/RoSystemProperties.java +++ b/core/java/com/android/internal/os/RoSystemProperties.java @@ -30,6 +30,14 @@ public class RoSystemProperties { public static final String CONTROL_PRIVAPP_PERMISSIONS = SystemProperties.get("ro.control_privapp_permissions"); + /** + * Property to indicate if a CEC audio device should forward volume keys when system audio + * mode is off. + */ + public static final boolean CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF = + SystemProperties.getBoolean( + "ro.hdmi.cec_audio_device_forward_volume_keys_system_audio_mode_off", false); + // ------ ro.config.* -------- // public static final boolean CONFIG_AVOID_GFX_ACCEL = SystemProperties.getBoolean("ro.config.avoid_gfx_accel", false); diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java index 9f2434e97d7a..0b329d70f7af 100644 --- a/core/java/com/android/internal/os/WebViewZygoteInit.java +++ b/core/java/com/android/internal/os/WebViewZygoteInit.java @@ -18,11 +18,7 @@ package com.android.internal.os; import android.app.ApplicationLoaders; import android.net.LocalSocket; -import android.net.LocalServerSocket; import android.os.Build; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; import android.text.TextUtils; import android.util.Log; import android.webkit.WebViewFactory; @@ -44,8 +40,6 @@ import java.lang.reflect.Method; class WebViewZygoteInit { public static final String TAG = "WebViewZygoteInit"; - private static ZygoteServer sServer; - private static class WebViewZygoteServer extends ZygoteServer { @Override protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList) @@ -127,48 +121,7 @@ class WebViewZygoteInit { public static void main(String argv[]) { Log.i(TAG, "Starting WebViewZygoteInit"); - - String socketName = null; - for (String arg : argv) { - Log.i(TAG, arg); - if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) { - socketName = arg.substring(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG.length()); - } - } - if (socketName == null) { - throw new RuntimeException("No " + Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + " specified"); - } - - try { - Os.prctl(OsConstants.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); - } catch (ErrnoException ex) { - throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); - } - - sServer = new WebViewZygoteServer(); - - final Runnable caller; - try { - sServer.registerServerSocketAtAbstractName(socketName); - - // Add the abstract socket to the FD whitelist so that the native zygote code - // can properly detach it after forking. - Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName); - - // The select loop returns early in the child process after a fork and - // loops forever in the zygote. - caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS)); - } catch (RuntimeException e) { - Log.e(TAG, "Fatal exception:", e); - throw e; - } finally { - sServer.closeServerSocket(); - } - - // We're in the child process and have exited the select loop. Proceed to execute the - // command. - if (caller != null) { - caller.run(); - } + WebViewZygoteServer server = new WebViewZygoteServer(); + ChildZygoteInit.runZygoteServer(server, argv); } } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 65b9fad97d89..d720c689f5de 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -98,6 +98,12 @@ public final class Zygote { */ public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket="; + /** + * An extraArg passed when a zygote process is forking a child-zygote, specifying the + * requested ABI for the child Zygote. + */ + public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list="; + private Zygote() {} /** Called for some security initialization before any fork. */ diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index f182c4d447df..5990d72d89b4 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -27,9 +27,11 @@ import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEO import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC; import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; +import android.content.pm.ApplicationInfo; import android.net.Credentials; import android.net.LocalSocket; import android.os.FactoryTest; +import android.os.Parcel; import android.os.Process; import android.os.SystemProperties; import android.os.Trace; @@ -52,6 +54,7 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; /** * A connection that can make spawn requests. @@ -168,6 +171,21 @@ class ZygoteConnection { return null; } + if (canPreloadApp() && parsedArgs.mPreloadApp != null) { + byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp); + Parcel appInfoParcel = Parcel.obtain(); + appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length); + appInfoParcel.setDataPosition(0); + ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel); + appInfoParcel.recycle(); + if (appInfo != null) { + handlePreloadApp(appInfo); + } else { + throw new IllegalArgumentException("Failed to deserialize --preload-app"); + } + return null; + } + if (parsedArgs.apiBlacklistExemptions != null) { handleApiBlacklistExemptions(parsedArgs.apiBlacklistExemptions); return null; @@ -341,7 +359,15 @@ class ZygoteConnection { protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName, String cacheKey) { - throw new RuntimeException("Zyogte does not support package preloading"); + throw new RuntimeException("Zygote does not support package preloading"); + } + + protected boolean canPreloadApp() { + return false; + } + + protected void handlePreloadApp(ApplicationInfo aInfo) { + throw new RuntimeException("Zygote does not support app preloading"); } /** @@ -467,6 +493,12 @@ class ZygoteConnection { String preloadPackage; /** + * A Base64 string representing a serialize ApplicationInfo Parcel, + when using --preload-app. + */ + String mPreloadApp; + + /** * The native library path of the package to preload, when using --preload-package. */ String preloadPackageLibs; @@ -666,6 +698,8 @@ class ZygoteConnection { instructionSet = arg.substring(arg.indexOf('=') + 1); } else if (arg.startsWith("--app-data-dir=")) { appDataDir = arg.substring(arg.indexOf('=') + 1); + } else if (arg.equals("--preload-app")) { + mPreloadApp = args[++curArg]; } else if (arg.equals("--preload-package")) { preloadPackage = args[++curArg]; preloadPackageLibs = args[++curArg]; @@ -714,6 +748,11 @@ class ZygoteConnection { throw new IllegalArgumentException( "Unexpected arguments after --preload-package."); } + } else if (mPreloadApp != null) { + if (args.length - curArg > 0) { + throw new IllegalArgumentException( + "Unexpected arguments after --preload-app."); + } } else if (expectRuntimeArgs) { if (!seenRuntimeArgs) { throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 6576587899be..6a4b633df6a2 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -916,6 +916,17 @@ static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) return reinterpret_cast<jlong>(surface.get()); } +static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) { + sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj)); + if (surface == nullptr) { + return 0; + } + + sp<SurfaceControl> newSurface = new SurfaceControl(surface); + newSurface->incStrong((void *)nativeCreate); + return reinterpret_cast<jlong>(newSurface.get()); +} + static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj) { Parcel* parcel = parcelForJavaObject(env, parcelObj); @@ -924,7 +935,9 @@ static void nativeWriteToParcel(JNIEnv* env, jclass clazz, return; } SurfaceControl* const self = reinterpret_cast<SurfaceControl *>(nativeObject); - self->writeToParcel(parcel); + if (self != nullptr) { + self->writeToParcel(parcel); + } } // ---------------------------------------------------------------------------- @@ -934,6 +947,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeCreate }, {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", (void*)nativeReadFromParcel }, + {"nativeCopyFromSurfaceControl", "(J)J" , + (void*)nativeCopyFromSurfaceControl }, {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, {"nativeRelease", "(J)V", diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp index 30c00302eefd..191f748d80bf 100644 --- a/core/jni/android_view_SurfaceSession.cpp +++ b/core/jni/android_view_SurfaceSession.cpp @@ -46,13 +46,6 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz) { return reinterpret_cast<jlong>(client); } -static jlong nativeCreateScoped(JNIEnv* env, jclass clazz, jlong surfaceObject) { - Surface *parent = reinterpret_cast<Surface*>(surfaceObject); - SurfaceComposerClient* client = new SurfaceComposerClient(parent->getIGraphicBufferProducer()); - client->incStrong((void*)nativeCreate); - return reinterpret_cast<jlong>(client); -} - static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) { SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr); client->decStrong((void*)nativeCreate); @@ -67,8 +60,6 @@ static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "nativeCreate", "()J", (void*)nativeCreate }, - { "nativeCreateScoped", "(J)J", - (void*)nativeCreateScoped }, { "nativeDestroy", "(J)V", (void*)nativeDestroy }, { "nativeKill", "(J)V", diff --git a/core/res/res/values-land/dimens_permission_controller.xml b/core/res/res/values-land/dimens_permission_controller.xml deleted file mode 100644 index 2146241fd830..000000000000 --- a/core/res/res/values-land/dimens_permission_controller.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2018 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. - --> - -<!-- Landscape dimensions for the permission grant dialog. --> -<resources> - <!-- Assuming the dimension of a sailfish, this yields 95% width in splitscreen and 65% in - landscape --> - <dimen name="permissionGrantDialogWeight">8.6</dimen> - <dimen name="permissionGrantDialogWidth">334dp</dimen> -</resources> diff --git a/core/res/res/values-night/themes_permission_controller.xml b/core/res/res/values-night/themes_permission_controller.xml deleted file mode 100644 index a071927f46b2..000000000000 --- a/core/res/res/values-night/themes_permission_controller.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2018 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. - --> - -<!-- themes for the permission grant dialog. --> -<resources> - <style name="Theme.DeviceDefault.PermissionGrantApp" - parent="@style/Theme.DeviceDefault.Panel"> - <item name="windowIsFloating">false</item> - <item name="windowTranslucentStatus">true</item> - <item name="backgroundDimEnabled">true</item> - <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item> - </style> - - <style name="Theme.DeviceDefault.PermissionGrant" - parent="@style/Theme.DeviceDefault.Dialog"> - <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item> - </style> -</resources> diff --git a/core/res/res/values-port/dimens_permission_controller.xml b/core/res/res/values-port/dimens_permission_controller.xml deleted file mode 100644 index af28713e5ba2..000000000000 --- a/core/res/res/values-port/dimens_permission_controller.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2018 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. - --> - -<!-- portrait dimensions for the permission grant dialog. --> -<resources> - <!-- This yields 95% width --> - <dimen name="permissionGrantDialogWeight">380</dimen> - <dimen name="permissionGrantDialogWidth">0dp</dimen> -</resources> diff --git a/core/res/res/values/styles_permission_controller.xml b/core/res/res/values/styles_permission_controller.xml deleted file mode 100644 index 5a9d3e6c2889..000000000000 --- a/core/res/res/values/styles_permission_controller.xml +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2018 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. - --> - -<resources> - <!-- styles for the permission grant dialog. --> - <style name="PermissionGrantDialog"> - <item name="background">?attr/windowBackground</item> - <item name="elevation">?attr/windowElevation</item> - <item name="layout_weight">@dimen/permissionGrantDialogWeight</item> - <item name="layout_width">@dimen/permissionGrantDialogWidth</item> - </style> - - <style name="PermissionGrantTitleIcon"> - <item name="layout_width">24dp</item> - <item name="layout_height">24dp</item> - <item name="layout_marginBottom">12dp</item> - <item name="tint">?attr/colorAccent</item> - <item name="scaleType">fitCenter</item> - </style> - - <style name="PermissionGrantTitleMessage" - parent="@style/TextAppearance.DeviceDefault"> - <item name="gravity">center</item> - <item name="textSize">20sp</item> - <item name="textColor">?attr/textColorPrimary</item> - </style> - - <style name="PermissionGrantIndex" - parent="@style/TextAppearance.DeviceDefault"> - <item name="paddingEnd">12dp</item> - <item name="singleLine">true</item> - <item name="textColor">?attr/textColorSecondary</item> - </style> - - <style name="PermissionGrantDescription"> - <item name="layout_marginStart">24dp</item> - <item name="layout_marginEnd">24dp</item> - </style> - - <style name="PermissionGrantContent"> - <item name="layout_marginStart">24dp</item> - <item name="layout_marginEnd">24dp</item> - </style> - - <style name="PermissionGrantDetailMessage" - parent="@style/TextAppearance.DeviceDefault"> - <item name="layout_marginTop">18dp</item> - <item name="textColor">?attr/textColorPrimary</item> - <item name="textSize">16sp</item> - </style> - - <!-- styles for the permission review screen. --> - <style name="PermissionReviewDescription"> - <item name="layout_marginTop">20dp</item> - <item name="layout_marginStart">24dp</item> - <item name="layout_marginBottom">16dp</item> - <item name="layout_marginEnd">24dp</item> - </style> - - <style name="PermissionReviewTitleIcon"> - <item name="layout_marginTop">4dp</item> - <item name="layout_width">36dp</item> - <item name="layout_height">36dp</item> - <item name="scaleType">fitCenter</item> - </style> - - <style name="PermissionReviewTitleMessage" - parent="@style/TextAppearance.DeviceDefault"> - <item name="paddingStart">22dp</item> - <item name="textSize">20sp</item> - <item name="textColor">?attr/textColorPrimary</item> - </style> - - <style name="PermissionReviewSettings"> - <item name="layout_marginStart">8dp</item> - <item name="layout_marginEnd">8dp</item> - </style> - - <style name="PermissionReviewButtonBar"> - <item name="layout_marginStart">24dp</item> - <item name="layout_marginEnd">16dp</item> - <item name="layout_marginBottom">4dp</item> - </style> -</resources> diff --git a/core/res/res/values/themes_permission_controller.xml b/core/res/res/values/themes_permission_controller.xml deleted file mode 100644 index 205c4eb2d9a2..000000000000 --- a/core/res/res/values/themes_permission_controller.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2018 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. - --> - -<resources> - <!-- themes for the permission grant dialog. --> - <style name="Theme.DeviceDefault.PermissionGrantApp" - parent="@style/Theme.DeviceDefault.Light.Panel"> - <item name="windowIsFloating">false</item> - <item name="windowTranslucentStatus">true</item> - <item name="backgroundDimEnabled">true</item> - <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item> - </style> - - <style name="Theme.DeviceDefault.PermissionGrant" - parent="@style/Theme.DeviceDefault.Light.Dialog"> - <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item> - </style> - - <!-- themes for the permission review dialog. --> - <style name="Theme.DeviceDefault.PermissionReviewApp" - parent="@style/Theme.DeviceDefault.Settings"> - <item name="windowActionBar">false</item> - <item name="windowNoTitle">true</item> - <item name="titleTextStyle">@style/PermissionReviewTitleMessage</item> - </style> -</resources> diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml index 6a4079256268..04bf804f091a 100644 --- a/data/fonts/fonts.xml +++ b/data/fonts/fonts.xml @@ -312,9 +312,8 @@ <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font> </family> <family lang="und-Mymr" variant="elegant"> - <font weight="400" style="normal">NotoSansMyanmar-Regular.otf</font> - <font weight="500" style="normal">NotoSansMyanmar-Medium.otf</font> - <font weight="700" style="normal">NotoSansMyanmar-Bold.otf</font> + <font weight="400" style="normal">NotoSansMyanmar-Regular-ZawDecode.ttf</font> + <font weight="700" style="normal">NotoSansMyanmar-Bold-ZawDecode.ttf</font> <font weight="400" style="normal" fallbackFor="serif">NotoSerifMyanmar-Regular.otf</font> <font weight="700" style="normal" fallbackFor="serif">NotoSerifMyanmar-Bold.otf</font> </family> diff --git a/data/sounds/AllAudio.mk b/data/sounds/AllAudio.mk index bb8add1187e7..c6c7d3bca724 100644 --- a/data/sounds/AllAudio.mk +++ b/data/sounds/AllAudio.mk @@ -15,227 +15,227 @@ LOCAL_PATH := frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \ - $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ - $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \ - $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \ - $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ - $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \ - $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \ - $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \ - $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \ - $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \ - $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \ - $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg \ - $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \ - $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \ - $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \ - $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \ - $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \ - $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \ - $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \ - $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \ - $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \ - $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \ - $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \ - $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \ - $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \ - $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \ - $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \ - $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \ - $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \ - $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \ - $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \ - $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \ - $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \ - $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \ - $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \ - $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ - $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \ - $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \ - $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \ - $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \ - $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \ - $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \ - $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \ - $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \ - $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \ - $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \ - $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \ - $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \ - $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg \ - $(LOCAL_PATH)/ringtones/ANDROMEDA.ogg:system/media/audio/ringtones/ANDROMEDA.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \ - $(LOCAL_PATH)/ringtones/BOOTES.ogg:system/media/audio/ringtones/BOOTES.ogg \ - $(LOCAL_PATH)/newwavelabs/Backroad.ogg:system/media/audio/ringtones/Backroad.ogg \ - $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \ - $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \ - $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \ - $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \ - $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \ - $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \ - $(LOCAL_PATH)/ringtones/CANISMAJOR.ogg:system/media/audio/ringtones/CANISMAJOR.ogg \ - $(LOCAL_PATH)/ringtones/CASSIOPEIA.ogg:system/media/audio/ringtones/CASSIOPEIA.ogg \ - $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \ - $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \ - $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \ - $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \ - $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \ - $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \ - $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \ - $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \ - $(LOCAL_PATH)/newwavelabs/Ding.ogg:system/media/audio/ringtones/Ding.ogg \ - $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ - $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \ - $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \ - $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:system/media/audio/ringtones/Enter_the_Nexus.ogg \ - $(LOCAL_PATH)/ringtones/Eridani.ogg:system/media/audio/ringtones/Eridani.ogg \ - $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \ - $(LOCAL_PATH)/ringtones/FreeFlight.ogg:system/media/audio/ringtones/FreeFlight.ogg \ - $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \ - $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \ - $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \ - $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \ - $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \ - $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \ - $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \ - $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \ - $(LOCAL_PATH)/ringtones/Lyra.ogg:system/media/audio/ringtones/Lyra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \ - $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \ - $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:system/media/audio/ringtones/Nairobi.ogg \ - $(LOCAL_PATH)/newwavelabs/Nassau.ogg:system/media/audio/ringtones/Nassau.ogg \ - $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \ - $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \ - $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/PERSEUS.ogg:system/media/audio/ringtones/PERSEUS.ogg \ - $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \ - $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \ - $(LOCAL_PATH)/newwavelabs/Revelation.ogg:system/media/audio/ringtones/Revelation.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \ - $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \ - $(LOCAL_PATH)/newwavelabs/Safari.ogg:system/media/audio/ringtones/Safari.ogg \ - $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \ - $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \ - $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \ - $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \ - $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \ - $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \ - $(LOCAL_PATH)/ringtones/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \ - $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg \ - $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \ - $(LOCAL_PATH)/ringtones/URSAMINOR.ogg:system/media/audio/ringtones/URSAMINOR.ogg \ - $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \ - $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \ - $(LOCAL_PATH)/ringtones/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg \ - $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg \ - $(LOCAL_PATH)/ringtones/hydra.ogg:system/media/audio/ringtones/hydra.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:system/media/audio/ui/ChargingStarted.ogg \ - $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:system/media/audio/ui/InCallNotification.ogg \ - $(LOCAL_PATH)/effects/ogg/NFCFailure.ogg:system/media/audio/ui/NFCFailure.ogg \ - $(LOCAL_PATH)/effects/ogg/NFCInitiated.ogg:system/media/audio/ui/NFCInitiated.ogg \ - $(LOCAL_PATH)/effects/ogg/NFCSuccess.ogg:system/media/audio/ui/NFCSuccess.ogg \ - $(LOCAL_PATH)/effects/ogg/NFCTransferComplete.ogg:system/media/audio/ui/NFCTransferComplete.ogg \ - $(LOCAL_PATH)/effects/ogg/NFCTransferInitiated.ogg:system/media/audio/ui/NFCTransferInitiated.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Rooster_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Rooster_02.ogg \ + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Barium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Barium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Cesium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Fermium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Hassium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neptunium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Nobelium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Plutonium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Promethium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Scandium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/Aldebaran.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Aldebaran.ogg \ + $(LOCAL_PATH)/notifications/Altair.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Altair.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/Antares.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Antares.ogg \ + $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Antimony.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Argon.ogg \ + $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beat_Box_Android.ogg \ + $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Bellatrix.ogg \ + $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beryllium.ogg \ + $(LOCAL_PATH)/notifications/Betelgeuse.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Betelgeuse.ogg \ + $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CaffeineSnake.ogg \ + $(LOCAL_PATH)/notifications/Canopus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Canopus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/Castor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Castor.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Cobalt.ogg \ + $(LOCAL_PATH)/notifications/Cricket.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Cricket.ogg \ + $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DearDeer.ogg \ + $(LOCAL_PATH)/notifications/Deneb.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Deneb.ogg \ + $(LOCAL_PATH)/notifications/Doink.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Doink.ogg \ + $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DontPanic.ogg \ + $(LOCAL_PATH)/notifications/Drip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Drip.ogg \ + $(LOCAL_PATH)/notifications/Electra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Electra.ogg \ + $(LOCAL_PATH)/F1_MissedCall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_MissedCall.ogg \ + $(LOCAL_PATH)/F1_New_MMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_MMS.ogg \ + $(LOCAL_PATH)/F1_New_SMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_SMS.ogg \ + $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Fluorine.ogg \ + $(LOCAL_PATH)/notifications/Fomalhaut.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Fomalhaut.ogg \ + $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Gallium.ogg \ + $(LOCAL_PATH)/notifications/Heaven.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Heaven.ogg \ + $(LOCAL_PATH)/notifications/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Helium.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Iridium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Krypton.ogg \ + $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/KzurbSonar.ogg \ + $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Lalande.ogg \ + $(LOCAL_PATH)/notifications/Merope.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Merope.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/OnTheHunt.ogg \ + $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Palladium.ogg \ + $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Plastic_Pipe.ogg \ + $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Proxima.ogg \ + $(LOCAL_PATH)/notifications/ogg/Radon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Radon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Rubidium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Selenium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/Sirrah.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Sirrah.ogg \ + $(LOCAL_PATH)/notifications/SpaceSeed.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/SpaceSeed.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Strontium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/TaDa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/TaDa.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Thallium.ogg \ + $(LOCAL_PATH)/notifications/Tinkerbell.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tinkerbell.ogg \ + $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Upsilon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/newwavelabs/Voila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Voila.ogg \ + $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Xenon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Zirconium.ogg \ + $(LOCAL_PATH)/notifications/arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/arcturus.ogg \ + $(LOCAL_PATH)/notifications/moonbeam.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/moonbeam.ogg \ + $(LOCAL_PATH)/notifications/pixiedust.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pixiedust.ogg \ + $(LOCAL_PATH)/notifications/pizzicato.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pizzicato.ogg \ + $(LOCAL_PATH)/notifications/regulus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/regulus.ogg \ + $(LOCAL_PATH)/notifications/sirius.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/sirius.ogg \ + $(LOCAL_PATH)/notifications/tweeters.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/tweeters.ogg \ + $(LOCAL_PATH)/notifications/vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/vega.ogg \ + $(LOCAL_PATH)/ringtones/ANDROMEDA.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ANDROMEDA.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Atria.ogg \ + $(LOCAL_PATH)/ringtones/BOOTES.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BOOTES.ogg \ + $(LOCAL_PATH)/newwavelabs/Backroad.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Backroad.ogg \ + $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BeatPlucker.ogg \ + $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BentleyDubs.ogg \ + $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Big_Easy.ogg \ + $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BirdLoop.ogg \ + $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Bollywood.ogg \ + $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BussaMove.ogg \ + $(LOCAL_PATH)/ringtones/CANISMAJOR.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CANISMAJOR.ogg \ + $(LOCAL_PATH)/ringtones/CASSIOPEIA.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CASSIOPEIA.ogg \ + $(LOCAL_PATH)/newwavelabs/Cairo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cairo.ogg \ + $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Calypso_Steel.ogg \ + $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CanisMajor.ogg \ + $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CaribbeanIce.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Carina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Champagne_Edition.ogg \ + $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Club_Cubano.ogg \ + $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrayonRock.ogg \ + $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrazyDream.ogg \ + $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CurveBall.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DancinFool.ogg \ + $(LOCAL_PATH)/newwavelabs/Ding.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ding.ogg \ + $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DonMessWivIt.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DreamTheme.ogg \ + $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eastern_Sky.ogg \ + $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Enter_the_Nexus.ogg \ + $(LOCAL_PATH)/ringtones/Eridani.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eridani.ogg \ + $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/EtherShake.ogg \ + $(LOCAL_PATH)/ringtones/FreeFlight.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/FreeFlight.ogg \ + $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/FriendlyGhost.ogg \ + $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Funk_Yall.ogg \ + $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/GameOverGuitar.ogg \ + $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Gimme_Mo_Town.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Glacial_Groove.ogg \ + $(LOCAL_PATH)/newwavelabs/Growl.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Growl.ogg \ + $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/HalfwayHome.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/InsertCoin.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Kuma.ogg \ + $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoopyLounge.ogg \ + $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoveFlute.ogg \ + $(LOCAL_PATH)/ringtones/Lyra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Lyra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MidEvilJaunt.ogg \ + $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MildlyAlarming.ogg \ + $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Nairobi.ogg \ + $(LOCAL_PATH)/newwavelabs/Nassau.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Nassau.ogg \ + $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/NewPlayer.ogg \ + $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/No_Limits.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises1.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises1.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises2.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises2.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises3.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises3.ogg \ + $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/OrganDub.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/PERSEUS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/PERSEUS.ogg \ + $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Paradise_Island.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Perseus.ogg \ + $(LOCAL_PATH)/newwavelabs/Playa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Playa.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rasalas.ogg \ + $(LOCAL_PATH)/newwavelabs/Revelation.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Revelation.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rigel.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Road_Trip.ogg \ + $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/RomancingTheTone.ogg \ + $(LOCAL_PATH)/newwavelabs/Safari.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Safari.ogg \ + $(LOCAL_PATH)/newwavelabs/Savannah.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Savannah.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/newwavelabs/Seville.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Seville.ogg \ + $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Shes_All_That.ogg \ + $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SilkyWay.ogg \ + $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SitarVsSitar.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SpringyJalopy.ogg \ + $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Steppin_Out.ogg \ + $(LOCAL_PATH)/newwavelabs/Terminated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Terminated.ogg \ + $(LOCAL_PATH)/ringtones/Testudo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Testudo.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Third_Eye.ogg \ + $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Thunderfoot.ogg \ + $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/TwirlAway.ogg \ + $(LOCAL_PATH)/ringtones/URSAMINOR.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/URSAMINOR.ogg \ + $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/UrsaMinor.ogg \ + $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/VeryAlarmed.ogg \ + $(LOCAL_PATH)/ringtones/Vespa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Vespa.ogg \ + $(LOCAL_PATH)/newwavelabs/World.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/World.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg \ + $(LOCAL_PATH)/ringtones/hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/hydra.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/WirelessChargingStarted.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/ChargingStarted.ogg \ + $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/InCallNotification.ogg \ + $(LOCAL_PATH)/effects/ogg/NFCFailure.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/NFCFailure.ogg \ + $(LOCAL_PATH)/effects/ogg/NFCInitiated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/NFCInitiated.ogg \ + $(LOCAL_PATH)/effects/ogg/NFCSuccess.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/NFCSuccess.ogg \ + $(LOCAL_PATH)/effects/ogg/NFCTransferComplete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/NFCTransferComplete.ogg \ + $(LOCAL_PATH)/effects/ogg/NFCTransferInitiated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/NFCTransferInitiated.ogg \ diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk index 72aa7fe1c38a..699dbd68048d 100644 --- a/data/sounds/AudioPackage10.mk +++ b/data/sounds/AudioPackage10.mk @@ -8,63 +8,63 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock_48k.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock_48k.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:system/media/audio/ui/ChargingStarted.ogg \ - $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:system/media/audio/ui/InCallNotification.ogg \ - $(LOCAL_PATH)/effects/material/ogg/WirelessChargingStarted_48k.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ - $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/ChargingStarted.ogg \ + $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/InCallNotification.ogg \ + $(LOCAL_PATH)/effects/material/ogg/WirelessChargingStarted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/WirelessChargingStarted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Atria.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Kuma.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rasalas.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage11.mk b/data/sounds/AudioPackage11.mk index 665ce521690e..99dfd0a6d455 100644 --- a/data/sounds/AudioPackage11.mk +++ b/data/sounds/AudioPackage11.mk @@ -8,63 +8,63 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock_48k.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock_48k.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:system/media/audio/ui/ChargingStarted.ogg \. - $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:system/media/audio/ui/InCallNotification.ogg \ - $(LOCAL_PATH)/effects/material/ogg/WirelessChargingStarted_48k.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ - $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat_proc48.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/effects/ogg/ChargingStarted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/ChargingStarted.ogg \. + $(LOCAL_PATH)/effects/ogg/InCallNotification.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/InCallNotification.ogg \ + $(LOCAL_PATH)/effects/material/ogg/WirelessChargingStarted_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/WirelessChargingStarted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat_proc48.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Atria.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Atria.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Kuma.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rasalas.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage12.mk b/data/sounds/AudioPackage12.mk index 44a8f9e34cd3..6159a89e8489 100644 --- a/data/sounds/AudioPackage12.mk +++ b/data/sounds/AudioPackage12.mk @@ -16,15 +16,15 @@ EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete Keypre MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingStarted VideoStop PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\ - $(LOCAL_PATH)/alarms/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg) + $(LOCAL_PATH)/alarms/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(NOTIFICATION_FILES),\ - $(LOCAL_PATH)/notifications/ogg/$(fn).ogg:system/media/audio/notifications/$(fn).ogg) + $(LOCAL_PATH)/notifications/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(RINGTONE_FILES),\ - $(LOCAL_PATH)/ringtones/ogg/$(fn).ogg:system/media/audio/ringtones/$(fn).ogg) + $(LOCAL_PATH)/ringtones/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(EFFECT_FILES),\ - $(LOCAL_PATH)/effects/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(MATERIAL_EFFECT_FILES),\ - $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) diff --git a/data/sounds/AudioPackage12_48.mk b/data/sounds/AudioPackage12_48.mk index 09fab041505e..2899cd160d24 100644 --- a/data/sounds/AudioPackage12_48.mk +++ b/data/sounds/AudioPackage12_48.mk @@ -17,21 +17,21 @@ MATERIAL_EFFECT_FILES := camera_click VideoRecord LowBattery WirelessChargingSta # Alarms not yet available in 48 kHz PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\ - $(LOCAL_PATH)/alarms/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg) + $(LOCAL_PATH)/alarms/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(NOTIFICATION_FILES),\ - $(LOCAL_PATH)/notifications/ogg/$(fn)_48k.ogg:system/media/audio/notifications/$(fn).ogg) + $(LOCAL_PATH)/notifications/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(RINGTONE_FILES),\ - $(LOCAL_PATH)/ringtones/ogg/$(fn)_48k.ogg:system/media/audio/ringtones/$(fn).ogg) + $(LOCAL_PATH)/ringtones/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(EFFECT_FILES),\ - $(LOCAL_PATH)/effects/ogg/$(fn)_48k.ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(MATERIAL_EFFECT_FILES),\ - $(LOCAL_PATH)/effects/material/ogg/$(fn)_48k.ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/material/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) # no gold-plated version yet PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg diff --git a/data/sounds/AudioPackage13.mk b/data/sounds/AudioPackage13.mk index de4ee047986d..9423c0b9ba5b 100644 --- a/data/sounds/AudioPackage13.mk +++ b/data/sounds/AudioPackage13.mk @@ -17,15 +17,15 @@ EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete Keypre MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery VideoStop PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\ - $(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg) + $(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(NOTIFICATION_FILES),\ - $(LOCAL_PATH)/notifications/material/ogg/$(fn).ogg:system/media/audio/notifications/$(fn).ogg) + $(LOCAL_PATH)/notifications/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(RINGTONE_FILES),\ - $(LOCAL_PATH)/ringtones/material/ogg/$(fn).ogg:system/media/audio/ringtones/$(fn).ogg) + $(LOCAL_PATH)/ringtones/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(EFFECT_FILES),\ - $(LOCAL_PATH)/effects/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(MATERIAL_EFFECT_FILES),\ - $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) diff --git a/data/sounds/AudioPackage13_48.mk b/data/sounds/AudioPackage13_48.mk index 889d58172290..806c4e26152b 100644 --- a/data/sounds/AudioPackage13_48.mk +++ b/data/sounds/AudioPackage13_48.mk @@ -17,21 +17,21 @@ EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete Keypre MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery VideoStop PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\ - $(LOCAL_PATH)/alarms/material/ogg/$(fn)_48k.ogg:system/media/audio/alarms/$(fn).ogg) + $(LOCAL_PATH)/alarms/material/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(NOTIFICATION_FILES),\ - $(LOCAL_PATH)/notifications/material/ogg/$(fn)_48k.ogg:system/media/audio/notifications/$(fn).ogg) + $(LOCAL_PATH)/notifications/material/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(RINGTONE_FILES),\ - $(LOCAL_PATH)/ringtones/material/ogg/$(fn)_48k.ogg:system/media/audio/ringtones/$(fn).ogg) + $(LOCAL_PATH)/ringtones/material/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(EFFECT_FILES),\ - $(LOCAL_PATH)/effects/ogg/$(fn)_48k.ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(MATERIAL_EFFECT_FILES),\ - $(LOCAL_PATH)/effects/material/ogg/$(fn)_48k.ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/material/ogg/$(fn)_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) # no gold-plated version yet PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg diff --git a/data/sounds/AudioPackage14.mk b/data/sounds/AudioPackage14.mk index c903a2b0eb97..3d161aabbf95 100644 --- a/data/sounds/AudioPackage14.mk +++ b/data/sounds/AudioPackage14.mk @@ -18,15 +18,15 @@ EFFECT_FILES := Effect_Tick KeypressReturn KeypressInvalid KeypressDelete Keypre MATERIAL_EFFECT_FILES := camera_click VideoRecord WirelessChargingStarted LowBattery VideoStop PRODUCT_COPY_FILES += $(foreach fn,$(ALARM_FILES),\ - $(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:system/media/audio/alarms/$(fn).ogg) + $(LOCAL_PATH)/alarms/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(NOTIFICATION_FILES),\ - $(LOCAL_PATH)/notifications/material/ogg/$(fn).ogg:system/media/audio/notifications/$(fn).ogg) + $(LOCAL_PATH)/notifications/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(RINGTONE_FILES),\ - $(LOCAL_PATH)/ringtones/material/ogg/$(fn).ogg:system/media/audio/ringtones/$(fn).ogg) + $(LOCAL_PATH)/ringtones/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(EFFECT_FILES),\ - $(LOCAL_PATH)/effects/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) PRODUCT_COPY_FILES += $(foreach fn,$(MATERIAL_EFFECT_FILES),\ - $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:system/media/audio/ui/$(fn).ogg) + $(LOCAL_PATH)/effects/material/ogg/$(fn).ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/$(fn).ogg) diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk index 40319c4505ec..bc4e8fbe811a 100644 --- a/data/sounds/AudioPackage2.mk +++ b/data/sounds/AudioPackage2.mk @@ -10,98 +10,98 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \ - $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \ - $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \ - $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \ - $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \ - $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \ - $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \ - $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \ - $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \ - $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \ - $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \ - $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg + $(LOCAL_PATH)/F1_MissedCall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_MissedCall.ogg \ + $(LOCAL_PATH)/F1_New_MMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_MMS.ogg \ + $(LOCAL_PATH)/F1_New_SMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_SMS.ogg \ + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/Alarm_Rooster_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Rooster_02.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beat_Box_Android.ogg \ + $(LOCAL_PATH)/notifications/Heaven.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Heaven.ogg \ + $(LOCAL_PATH)/notifications/TaDa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/TaDa.ogg \ + $(LOCAL_PATH)/notifications/Tinkerbell.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tinkerbell.ogg \ + $(LOCAL_PATH)/effects/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/moonbeam.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/moonbeam.ogg \ + $(LOCAL_PATH)/notifications/pixiedust.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pixiedust.ogg \ + $(LOCAL_PATH)/notifications/pizzicato.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pizzicato.ogg \ + $(LOCAL_PATH)/notifications/tweeters.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/tweeters.ogg \ + $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BeatPlucker.ogg \ + $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CaffeineSnake.ogg ifneq ($(MINIMAL_NEWWAVELABS),true) PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \ - $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \ - $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \ - $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \ - $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \ - $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \ - $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \ - $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \ - $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \ - $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \ - $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \ - $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \ - $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \ - $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \ - $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \ - $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \ - $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \ - $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \ - $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \ - $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \ - $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \ - $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \ - $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \ - $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \ - $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \ - $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \ - $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \ - $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \ - $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \ - $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \ - $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \ - $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \ - $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \ - $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \ - $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \ - $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \ - $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \ - $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \ - $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \ - $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \ - $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \ - $(LOCAL_PATH)/newwavelabs/Revelation.ogg:system/media/audio/ringtones/Revelation.ogg \ - $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \ - $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \ - $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \ - $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \ - $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \ - $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg + $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BentleyDubs.ogg \ + $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BirdLoop.ogg \ + $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CaribbeanIce.ogg \ + $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CurveBall.ogg \ + $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/EtherShake.ogg \ + $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/FriendlyGhost.ogg \ + $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/GameOverGuitar.ogg \ + $(LOCAL_PATH)/newwavelabs/Growl.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Growl.ogg \ + $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/InsertCoin.ogg \ + $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoopyLounge.ogg \ + $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoveFlute.ogg \ + $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MidEvilJaunt.ogg \ + $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MildlyAlarming.ogg \ + $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/NewPlayer.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises1.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises1.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises2.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises2.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises3.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises3.ogg \ + $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/OrganDub.ogg \ + $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/RomancingTheTone.ogg \ + $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SitarVsSitar.ogg \ + $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SpringyJalopy.ogg \ + $(LOCAL_PATH)/newwavelabs/Terminated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Terminated.ogg \ + $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/TwirlAway.ogg \ + $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/VeryAlarmed.ogg \ + $(LOCAL_PATH)/newwavelabs/World.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/World.ogg \ + $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DearDeer.ogg \ + $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DontPanic.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/KzurbSonar.ogg \ + $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/OnTheHunt.ogg \ + $(LOCAL_PATH)/newwavelabs/Voila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Voila.ogg \ + $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrazyDream.ogg \ + $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DreamTheme.ogg \ + $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Big_Easy.ogg \ + $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Bollywood.ogg \ + $(LOCAL_PATH)/newwavelabs/Cairo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cairo.ogg \ + $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Calypso_Steel.ogg \ + $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Champagne_Edition.ogg \ + $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Club_Cubano.ogg \ + $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eastern_Sky.ogg \ + $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Funk_Yall.ogg \ + $(LOCAL_PATH)/newwavelabs/Savannah.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Savannah.ogg \ + $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Gimme_Mo_Town.ogg \ + $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Glacial_Groove.ogg \ + $(LOCAL_PATH)/newwavelabs/Seville.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Seville.ogg \ + $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/No_Limits.ogg \ + $(LOCAL_PATH)/newwavelabs/Revelation.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Revelation.ogg \ + $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Paradise_Island.ogg \ + $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Road_Trip.ogg \ + $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Shes_All_That.ogg \ + $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Steppin_Out.ogg \ + $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Third_Eye.ogg \ + $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Thunderfoot.ogg endif diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk index a05de723c8f1..a98fb74a0f2a 100644 --- a/data/sounds/AudioPackage3.mk +++ b/data/sounds/AudioPackage3.mk @@ -10,94 +10,94 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \ - $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \ - $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \ - $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \ - $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \ - $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \ - $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \ - $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \ - $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \ - $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \ - $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \ - $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg + $(LOCAL_PATH)/F1_MissedCall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_MissedCall.ogg \ + $(LOCAL_PATH)/F1_New_MMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_MMS.ogg \ + $(LOCAL_PATH)/F1_New_SMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_SMS.ogg \ + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/Alarm_Rooster_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Rooster_02.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beat_Box_Android.ogg \ + $(LOCAL_PATH)/notifications/Heaven.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Heaven.ogg \ + $(LOCAL_PATH)/notifications/TaDa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/TaDa.ogg \ + $(LOCAL_PATH)/notifications/Tinkerbell.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tinkerbell.ogg \ + $(LOCAL_PATH)/effects/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/moonbeam.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/moonbeam.ogg \ + $(LOCAL_PATH)/notifications/pixiedust.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pixiedust.ogg \ + $(LOCAL_PATH)/notifications/pizzicato.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pizzicato.ogg \ + $(LOCAL_PATH)/notifications/tweeters.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/tweeters.ogg \ + $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BeatPlucker.ogg \ + $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CaffeineSnake.ogg ifneq ($(MINIMAL_NEWWAVELABS),true) PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \ - $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \ - $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \ - $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \ - $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \ - $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \ - $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \ - $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \ - $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \ - $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \ - $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \ - $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \ - $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \ - $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \ - $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \ - $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \ - $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \ - $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \ - $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \ - $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \ - $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \ - $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \ - $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \ - $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \ - $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \ - $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \ - $(LOCAL_PATH)/newwavelabs/Savannah.ogg:system/media/audio/ringtones/Savannah.ogg \ - $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \ - $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \ - $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \ - $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \ - $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \ - $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \ - $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \ - $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \ - $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \ - $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:system/media/audio/ringtones/Thunderfoot.ogg \ - $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \ - $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \ - $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \ - $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \ - $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \ - $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \ - $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg + $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BentleyDubs.ogg \ + $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BirdLoop.ogg \ + $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CurveBall.ogg \ + $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/EtherShake.ogg \ + $(LOCAL_PATH)/newwavelabs/Growl.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Growl.ogg \ + $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoopyLounge.ogg \ + $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoveFlute.ogg \ + $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MidEvilJaunt.ogg \ + $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MildlyAlarming.ogg \ + $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/NewPlayer.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises1.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises1.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises2.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises2.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises3.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises3.ogg \ + $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/OrganDub.ogg \ + $(LOCAL_PATH)/newwavelabs/Terminated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Terminated.ogg \ + $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/TwirlAway.ogg \ + $(LOCAL_PATH)/newwavelabs/World.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/World.ogg \ + $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DearDeer.ogg \ + $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DontPanic.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/KzurbSonar.ogg \ + $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/OnTheHunt.ogg \ + $(LOCAL_PATH)/newwavelabs/Voila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Voila.ogg \ + $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Big_Easy.ogg \ + $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Bollywood.ogg \ + $(LOCAL_PATH)/newwavelabs/Cairo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cairo.ogg \ + $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Calypso_Steel.ogg \ + $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Champagne_Edition.ogg \ + $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Club_Cubano.ogg \ + $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eastern_Sky.ogg \ + $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Funk_Yall.ogg \ + $(LOCAL_PATH)/newwavelabs/Savannah.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Savannah.ogg \ + $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Gimme_Mo_Town.ogg \ + $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Glacial_Groove.ogg \ + $(LOCAL_PATH)/newwavelabs/Seville.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Seville.ogg \ + $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/No_Limits.ogg \ + $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Paradise_Island.ogg \ + $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Road_Trip.ogg \ + $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Shes_All_That.ogg \ + $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Steppin_Out.ogg \ + $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Third_Eye.ogg \ + $(LOCAL_PATH)/newwavelabs/Thunderfoot.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Thunderfoot.ogg \ + $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/HalfwayHome.ogg \ + $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrayonRock.ogg \ + $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DancinFool.ogg \ + $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BussaMove.ogg \ + $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DonMessWivIt.ogg \ + $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SilkyWay.ogg \ + $(LOCAL_PATH)/newwavelabs/Playa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Playa.ogg endif diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk index d376a2d91f6c..54c3c025d978 100644 --- a/data/sounds/AudioPackage4.mk +++ b/data/sounds/AudioPackage4.mk @@ -10,98 +10,98 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \ - $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \ - $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \ - $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \ - $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \ - $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \ - $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \ - $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \ - $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \ - $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \ - $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \ - $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \ - $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \ - $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \ - $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \ - $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \ - $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/ringtones/FreeFlight.ogg:system/media/audio/ringtones/FreeFlight.ogg \ - $(LOCAL_PATH)/newwavelabs/Backroad.ogg:system/media/audio/ringtones/Backroad.ogg \ - $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg + $(LOCAL_PATH)/F1_MissedCall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_MissedCall.ogg \ + $(LOCAL_PATH)/F1_New_MMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_MMS.ogg \ + $(LOCAL_PATH)/F1_New_SMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_SMS.ogg \ + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/Alarm_Rooster_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Rooster_02.ogg \ + $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beat_Box_Android.ogg \ + $(LOCAL_PATH)/notifications/Cricket.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Cricket.ogg \ + $(LOCAL_PATH)/notifications/Doink.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Doink.ogg \ + $(LOCAL_PATH)/notifications/Drip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Drip.ogg \ + $(LOCAL_PATH)/notifications/Heaven.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Heaven.ogg \ + $(LOCAL_PATH)/notifications/SpaceSeed.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/SpaceSeed.ogg \ + $(LOCAL_PATH)/notifications/TaDa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/TaDa.ogg \ + $(LOCAL_PATH)/notifications/Tinkerbell.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tinkerbell.ogg \ + $(LOCAL_PATH)/notifications/moonbeam.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/moonbeam.ogg \ + $(LOCAL_PATH)/notifications/pixiedust.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pixiedust.ogg \ + $(LOCAL_PATH)/notifications/pizzicato.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pizzicato.ogg \ + $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Plastic_Pipe.ogg \ + $(LOCAL_PATH)/notifications/tweeters.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/tweeters.ogg \ + $(LOCAL_PATH)/effects/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/ringtones/FreeFlight.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/FreeFlight.ogg \ + $(LOCAL_PATH)/newwavelabs/Backroad.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Backroad.ogg \ + $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CaffeineSnake.ogg ifneq ($(MINIMAL_NEWWAVELABS),true) PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \ - $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \ - $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \ - $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \ - $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \ - $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \ - $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \ - $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:system/media/audio/ringtones/BussaMove.ogg \ - $(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \ - $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:system/media/audio/ringtones/Calypso_Steel.ogg \ - $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:system/media/audio/ringtones/Champagne_Edition.ogg \ - $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:system/media/audio/ringtones/Club_Cubano.ogg \ - $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:system/media/audio/ringtones/CrayonRock.ogg \ - $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \ - $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:system/media/audio/ringtones/DancinFool.ogg \ - $(LOCAL_PATH)/newwavelabs/Ding.ogg:system/media/audio/ringtones/Ding.ogg \ - $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:system/media/audio/ringtones/DonMessWivIt.ogg \ - $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:system/media/audio/ringtones/Eastern_Sky.ogg \ - $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:system/media/audio/ringtones/Enter_the_Nexus.ogg \ - $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \ - $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:system/media/audio/ringtones/Funk_Yall.ogg \ - $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:system/media/audio/ringtones/Gimme_Mo_Town.ogg \ - $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:system/media/audio/ringtones/Glacial_Groove.ogg \ - $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \ - $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:system/media/audio/ringtones/HalfwayHome.ogg \ - $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \ - $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \ - $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \ - $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \ - $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:system/media/audio/ringtones/Nairobi.ogg \ - $(LOCAL_PATH)/newwavelabs/Nassau.ogg:system/media/audio/ringtones/Nassau.ogg \ - $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:system/media/audio/ringtones/No_Limits.ogg \ - $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \ - $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:system/media/audio/ringtones/Paradise_Island.ogg \ - $(LOCAL_PATH)/newwavelabs/Playa.ogg:system/media/audio/ringtones/Playa.ogg \ - $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:system/media/audio/ringtones/Road_Trip.ogg \ - $(LOCAL_PATH)/newwavelabs/Safari.ogg:system/media/audio/ringtones/Safari.ogg \ - $(LOCAL_PATH)/newwavelabs/Seville.ogg:system/media/audio/ringtones/Seville.ogg \ - $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:system/media/audio/ringtones/Shes_All_That.ogg \ - $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:system/media/audio/ringtones/SilkyWay.ogg \ - $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:system/media/audio/ringtones/Steppin_Out.ogg \ - $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \ - $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:system/media/audio/ringtones/Third_Eye.ogg \ - $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \ - $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg + $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DearDeer.ogg \ + $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DontPanic.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/KzurbSonar.ogg \ + $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/OnTheHunt.ogg \ + $(LOCAL_PATH)/newwavelabs/Voila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Voila.ogg \ + $(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Big_Easy.ogg \ + $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BirdLoop.ogg \ + $(LOCAL_PATH)/newwavelabs/Bollywood.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Bollywood.ogg \ + $(LOCAL_PATH)/newwavelabs/BussaMove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BussaMove.ogg \ + $(LOCAL_PATH)/newwavelabs/Cairo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cairo.ogg \ + $(LOCAL_PATH)/newwavelabs/Calypso_Steel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Calypso_Steel.ogg \ + $(LOCAL_PATH)/newwavelabs/Champagne_Edition.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Champagne_Edition.ogg \ + $(LOCAL_PATH)/newwavelabs/Club_Cubano.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Club_Cubano.ogg \ + $(LOCAL_PATH)/newwavelabs/CrayonRock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrayonRock.ogg \ + $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CurveBall.ogg \ + $(LOCAL_PATH)/newwavelabs/DancinFool.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DancinFool.ogg \ + $(LOCAL_PATH)/newwavelabs/Ding.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ding.ogg \ + $(LOCAL_PATH)/newwavelabs/DonMessWivIt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DonMessWivIt.ogg \ + $(LOCAL_PATH)/newwavelabs/Eastern_Sky.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eastern_Sky.ogg \ + $(LOCAL_PATH)/newwavelabs/Enter_the_Nexus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Enter_the_Nexus.ogg \ + $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/EtherShake.ogg \ + $(LOCAL_PATH)/newwavelabs/Funk_Yall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Funk_Yall.ogg \ + $(LOCAL_PATH)/newwavelabs/Gimme_Mo_Town.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Gimme_Mo_Town.ogg \ + $(LOCAL_PATH)/newwavelabs/Glacial_Groove.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Glacial_Groove.ogg \ + $(LOCAL_PATH)/newwavelabs/Growl.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Growl.ogg \ + $(LOCAL_PATH)/newwavelabs/HalfwayHome.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/HalfwayHome.ogg \ + $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoopyLounge.ogg \ + $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoveFlute.ogg \ + $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MidEvilJaunt.ogg \ + $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MildlyAlarming.ogg \ + $(LOCAL_PATH)/newwavelabs/Nairobi.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Nairobi.ogg \ + $(LOCAL_PATH)/newwavelabs/Nassau.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Nassau.ogg \ + $(LOCAL_PATH)/newwavelabs/No_Limits.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/No_Limits.ogg \ + $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/OrganDub.ogg \ + $(LOCAL_PATH)/newwavelabs/Paradise_Island.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Paradise_Island.ogg \ + $(LOCAL_PATH)/newwavelabs/Playa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Playa.ogg \ + $(LOCAL_PATH)/newwavelabs/Road_Trip.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Road_Trip.ogg \ + $(LOCAL_PATH)/newwavelabs/Safari.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Safari.ogg \ + $(LOCAL_PATH)/newwavelabs/Seville.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Seville.ogg \ + $(LOCAL_PATH)/newwavelabs/Shes_All_That.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Shes_All_That.ogg \ + $(LOCAL_PATH)/newwavelabs/SilkyWay.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SilkyWay.ogg \ + $(LOCAL_PATH)/newwavelabs/Steppin_Out.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Steppin_Out.ogg \ + $(LOCAL_PATH)/newwavelabs/Terminated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Terminated.ogg \ + $(LOCAL_PATH)/newwavelabs/Third_Eye.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Third_Eye.ogg \ + $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/TwirlAway.ogg \ + $(LOCAL_PATH)/newwavelabs/World.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/World.ogg endif diff --git a/data/sounds/AudioPackage5.mk b/data/sounds/AudioPackage5.mk index 72384c8b9146..8a03a2e1eb1d 100644 --- a/data/sounds/AudioPackage5.mk +++ b/data/sounds/AudioPackage5.mk @@ -8,69 +8,69 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \ - $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \ - $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \ - $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \ - $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \ - $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \ - $(LOCAL_PATH)/notifications/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \ - $(LOCAL_PATH)/notifications/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \ - $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \ - $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \ - $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \ - $(LOCAL_PATH)/notifications/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ - $(LOCAL_PATH)/notifications/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \ - $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \ - $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \ - $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg \ - $(LOCAL_PATH)/ringtones/ANDROMEDA.ogg:system/media/audio/ringtones/ANDROMEDA.ogg \ - $(LOCAL_PATH)/ringtones/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/BOOTES.ogg:system/media/audio/ringtones/BOOTES.ogg \ - $(LOCAL_PATH)/ringtones/CANISMAJOR.ogg:system/media/audio/ringtones/CANISMAJOR.ogg \ - $(LOCAL_PATH)/ringtones/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/CASSIOPEIA.ogg:system/media/audio/ringtones/CASSIOPEIA.ogg \ - $(LOCAL_PATH)/ringtones/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/ringtones/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ - $(LOCAL_PATH)/ringtones/Eridani.ogg:system/media/audio/ringtones/Eridani.ogg \ - $(LOCAL_PATH)/ringtones/hydra.ogg:system/media/audio/ringtones/hydra.ogg \ - $(LOCAL_PATH)/ringtones/Lyra.ogg:system/media/audio/ringtones/Lyra.ogg \ - $(LOCAL_PATH)/ringtones/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/PERSEUS.ogg:system/media/audio/ringtones/PERSEUS.ogg \ - $(LOCAL_PATH)/ringtones/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \ - $(LOCAL_PATH)/ringtones/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \ - $(LOCAL_PATH)/ringtones/URSAMINOR.ogg:system/media/audio/ringtones/URSAMINOR.ogg \ - $(LOCAL_PATH)/ringtones/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/effects/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/Aldebaran.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Aldebaran.ogg \ + $(LOCAL_PATH)/notifications/Altair.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Altair.ogg \ + $(LOCAL_PATH)/notifications/Antares.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Antares.ogg \ + $(LOCAL_PATH)/notifications/arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/arcturus.ogg \ + $(LOCAL_PATH)/notifications/Betelgeuse.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Betelgeuse.ogg \ + $(LOCAL_PATH)/notifications/Canopus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Canopus.ogg \ + $(LOCAL_PATH)/notifications/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/Castor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Castor.ogg \ + $(LOCAL_PATH)/notifications/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/Deneb.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Deneb.ogg \ + $(LOCAL_PATH)/notifications/Electra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Electra.ogg \ + $(LOCAL_PATH)/notifications/Fomalhaut.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Fomalhaut.ogg \ + $(LOCAL_PATH)/notifications/Merope.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Merope.ogg \ + $(LOCAL_PATH)/notifications/Polaris.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/regulus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/regulus.ogg \ + $(LOCAL_PATH)/notifications/sirius.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/sirius.ogg \ + $(LOCAL_PATH)/notifications/Sirrah.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Sirrah.ogg \ + $(LOCAL_PATH)/notifications/vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/vega.ogg \ + $(LOCAL_PATH)/ringtones/ANDROMEDA.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ANDROMEDA.ogg \ + $(LOCAL_PATH)/ringtones/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/BOOTES.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BOOTES.ogg \ + $(LOCAL_PATH)/ringtones/CANISMAJOR.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CANISMAJOR.ogg \ + $(LOCAL_PATH)/ringtones/Carina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Carina.ogg \ + $(LOCAL_PATH)/ringtones/CASSIOPEIA.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CASSIOPEIA.ogg \ + $(LOCAL_PATH)/ringtones/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/ringtones/Draco.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/ringtones/Eridani.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Eridani.ogg \ + $(LOCAL_PATH)/ringtones/hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/hydra.ogg \ + $(LOCAL_PATH)/ringtones/Lyra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Lyra.ogg \ + $(LOCAL_PATH)/ringtones/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/PERSEUS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/PERSEUS.ogg \ + $(LOCAL_PATH)/ringtones/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/Rigel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rigel.ogg \ + $(LOCAL_PATH)/ringtones/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/Testudo.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Testudo.ogg \ + $(LOCAL_PATH)/ringtones/URSAMINOR.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/URSAMINOR.ogg \ + $(LOCAL_PATH)/ringtones/Vespa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Vespa.ogg diff --git a/data/sounds/AudioPackage6.mk b/data/sounds/AudioPackage6.mk index 5413704f0fac..a778261c0a22 100644 --- a/data/sounds/AudioPackage6.mk +++ b/data/sounds/AudioPackage6.mk @@ -8,41 +8,41 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \ - $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \ - $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \ - $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \ - $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \ - $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/alarms/ogg/Barium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Barium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Cesium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Plutonium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Scandium.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Antimony.ogg \ + $(LOCAL_PATH)/notifications/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Argon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beryllium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Cobalt.ogg \ + $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Fluorine.ogg \ + $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Gallium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Helium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Iridium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Krypton.ogg \ + $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Palladium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Radon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Radon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Rubidium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Selenium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Strontium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Thallium.ogg \ + $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Xenon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Zirconium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk index e4763be2d4aa..27e349d2262e 100644 --- a/data/sounds/AudioPackage7.mk +++ b/data/sounds/AudioPackage7.mk @@ -8,64 +8,64 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg + $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Cesium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Fermium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Hassium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neptunium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Nobelium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Plutonium.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Bellatrix.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Lalande.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Proxima.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Upsilon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CanisMajor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Carina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Perseus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rigel.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/UrsaMinor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage7alt.mk b/data/sounds/AudioPackage7alt.mk index 30e617316ef4..a0f4d89ff32c 100644 --- a/data/sounds/AudioPackage7alt.mk +++ b/data/sounds/AudioPackage7alt.mk @@ -8,63 +8,63 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg-jp/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg-jp/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ - $(LOCAL_PATH)/alarms/ogg-jp/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg-jp/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ - $(LOCAL_PATH)/alarms/ogg-jp/Neon.ogg:system/media/audio/alarms/Neon.ogg \ - $(LOCAL_PATH)/alarms/ogg-jp/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg + $(LOCAL_PATH)/alarms/ogg-jp/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg-jp/Carbon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg-jp/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg-jp/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg-jp/Neon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg-jp/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/ogg/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Bellatrix.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Lalande.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Proxima.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Upsilon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CanisMajor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Carina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Perseus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rigel.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/UrsaMinor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage8.mk b/data/sounds/AudioPackage8.mk index b38e62dec6ad..032b4d26ed6f 100644 --- a/data/sounds/AudioPackage8.mk +++ b/data/sounds/AudioPackage8.mk @@ -8,66 +8,66 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ - $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg + $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Cesium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Fermium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Hassium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neptunium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Nobelium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Plutonium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Promethium.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Bellatrix.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Lalande.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Proxima.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Upsilon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Andromeda.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Aquila.ogg \ + $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/ArgoNavis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CanisMajor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Carina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Centaurus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Hydra.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Machina.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Orion.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pegasus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Perseus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Pyxis.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Rigel.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Scarabaeus.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Sceptrum.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Solarium.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/UrsaMinor.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk index dbe1350f304a..53cc8c08a76c 100644 --- a/data/sounds/AudioPackage9.mk +++ b/data/sounds/AudioPackage9.mk @@ -8,43 +8,43 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \ - $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \ - $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \ - $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \ - $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ - $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ - $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ - $(LOCAL_PATH)/effects/ogg/Trusted.ogg:system/media/audio/ui/Trusted.ogg \ - $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ - $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ - $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ - $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ - $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ - $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ - $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ - $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \ - $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ - $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Carbon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Krypton.ogg \ + $(LOCAL_PATH)/alarms/ogg/Neon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Neon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Osmium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/material/ogg/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/material/ogg/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_focus.ogg \ + $(LOCAL_PATH)/effects/material/ogg/LowBattery.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/LowBattery.ogg \ + $(LOCAL_PATH)/effects/ogg/Dock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Dock.ogg \ + $(LOCAL_PATH)/effects/ogg/Undock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Undock.ogg \ + $(LOCAL_PATH)/effects/ogg/Lock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Lock.ogg \ + $(LOCAL_PATH)/effects/ogg/Unlock.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/Trusted.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Trusted.ogg \ + $(LOCAL_PATH)/notifications/ogg/Adara.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Adara.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Arcturus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Capella.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Capella.ogg \ + $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CetiAlpha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Hojus.ogg \ + $(LOCAL_PATH)/notifications/ogg/Mira.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Mira.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Pollux.ogg \ + $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Procyon.ogg \ + $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Shaula.ogg \ + $(LOCAL_PATH)/notifications/ogg/Spica.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Syrma.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Vega.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Vega.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Girtab.ogg diff --git a/data/sounds/AudioPackageGo.mk b/data/sounds/AudioPackageGo.mk index 0296219fe9b4..e3b27f2cd962 100644 --- a/data/sounds/AudioPackageGo.mk +++ b/data/sounds/AudioPackageGo.mk @@ -20,30 +20,30 @@ LOCAL_PATH := frameworks/base/data/sounds # Ring_Synth_04 : Flutey Phone # Alarm_Beep_03 : Beep Beep Beep PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ - $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \ - $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \ - $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \ - $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \ - $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \ - $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \ - $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \ - $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/notifications/ogg/Alya.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Alya.ogg \ + $(LOCAL_PATH)/notifications/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Argon.ogg \ + $(LOCAL_PATH)/notifications/Canopus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Canopus.ogg \ + $(LOCAL_PATH)/notifications/Deneb.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Deneb.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Iridium.ogg \ + $(LOCAL_PATH)/notifications/pixiedust.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/pixiedust.ogg \ + $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Talitha.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Cygnus.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Kuma.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Themos.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Themos.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/alarms/ogg/Argon.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Argon.ogg \ + $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Platinum.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/alarms/ogg/Helium.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Helium.ogg \ + $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Oxygen.ogg \ + $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk index 91265af77fa5..d0006b787f49 100644 --- a/data/sounds/AudioTv.mk +++ b/data/sounds/AudioTv.mk @@ -15,8 +15,8 @@ LOCAL_PATH := frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg + $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg diff --git a/data/sounds/OriginalAudio.mk b/data/sounds/OriginalAudio.mk index f68375205d89..4d74d1224caa 100644 --- a/data/sounds/OriginalAudio.mk +++ b/data/sounds/OriginalAudio.mk @@ -9,67 +9,67 @@ LOCAL_PATH:= frameworks/base/data/sounds PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \ - $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \ - $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \ - $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \ - $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \ - $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \ - $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \ - $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \ - $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \ - $(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \ - $(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \ - $(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \ - $(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \ - $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \ - $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \ - $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \ - $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \ - $(LOCAL_PATH)/effects/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \ - $(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \ - $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \ - $(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \ - $(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \ - $(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \ - $(LOCAL_PATH)/effects/VideoStop.ogg:system/media/audio/ui/VideoStop.ogg \ - $(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \ - $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \ - $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:system/media/audio/notifications/CaffeineSnake.ogg + $(LOCAL_PATH)/F1_MissedCall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_MissedCall.ogg \ + $(LOCAL_PATH)/F1_New_MMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_MMS.ogg \ + $(LOCAL_PATH)/F1_New_SMS.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/F1_New_SMS.ogg \ + $(LOCAL_PATH)/Alarm_Buzzer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Buzzer.ogg \ + $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_01.ogg \ + $(LOCAL_PATH)/Alarm_Beep_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \ + $(LOCAL_PATH)/Alarm_Classic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Classic.ogg \ + $(LOCAL_PATH)/Alarm_Beep_03.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_03.ogg \ + $(LOCAL_PATH)/Alarm_Rooster_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Rooster_02.ogg \ + $(LOCAL_PATH)/Ring_Classic_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Classic_02.ogg \ + $(LOCAL_PATH)/Ring_Digital_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Digital_02.ogg \ + $(LOCAL_PATH)/Ring_Synth_04.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_04.ogg \ + $(LOCAL_PATH)/Ring_Synth_02.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Ring_Synth_02.ogg \ + $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Beat_Box_Android.ogg \ + $(LOCAL_PATH)/notifications/Heaven.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Heaven.ogg \ + $(LOCAL_PATH)/notifications/TaDa.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/TaDa.ogg \ + $(LOCAL_PATH)/notifications/Tinkerbell.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Tinkerbell.ogg \ + $(LOCAL_PATH)/effects/Effect_Tick.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/Effect_Tick.ogg \ + $(LOCAL_PATH)/effects/KeypressStandard.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressStandard.ogg \ + $(LOCAL_PATH)/effects/KeypressSpacebar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressSpacebar.ogg \ + $(LOCAL_PATH)/effects/KeypressDelete.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \ + $(LOCAL_PATH)/effects/KeypressReturn.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \ + $(LOCAL_PATH)/effects/VideoRecord.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoRecord.ogg \ + $(LOCAL_PATH)/effects/VideoStop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/VideoStop.ogg \ + $(LOCAL_PATH)/effects/camera_click.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/camera_click.ogg \ + $(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BeatPlucker.ogg \ + $(LOCAL_PATH)/newwavelabs/CaffeineSnake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/CaffeineSnake.ogg ifneq ($(MINIMAL_NEWWAVELABS),true) PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \ - $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \ - $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:system/media/audio/ringtones/CaribbeanIce.ogg \ - $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:system/media/audio/ringtones/CurveBall.ogg \ - $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:system/media/audio/ringtones/EtherShake.ogg \ - $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:system/media/audio/ringtones/FriendlyGhost.ogg \ - $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:system/media/audio/ringtones/GameOverGuitar.ogg \ - $(LOCAL_PATH)/newwavelabs/Growl.ogg:system/media/audio/ringtones/Growl.ogg \ - $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:system/media/audio/ringtones/InsertCoin.ogg \ - $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:system/media/audio/ringtones/LoopyLounge.ogg \ - $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:system/media/audio/ringtones/LoveFlute.ogg \ - $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:system/media/audio/ringtones/MidEvilJaunt.ogg \ - $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:system/media/audio/ringtones/MildlyAlarming.ogg \ - $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:system/media/audio/ringtones/NewPlayer.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises1.ogg:system/media/audio/ringtones/Noises1.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises2.ogg:system/media/audio/ringtones/Noises2.ogg \ - $(LOCAL_PATH)/newwavelabs/Noises3.ogg:system/media/audio/ringtones/Noises3.ogg \ - $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:system/media/audio/ringtones/OrganDub.ogg \ - $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:system/media/audio/ringtones/RomancingTheTone.ogg \ - $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:system/media/audio/ringtones/SitarVsSitar.ogg \ - $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:system/media/audio/ringtones/SpringyJalopy.ogg \ - $(LOCAL_PATH)/newwavelabs/Terminated.ogg:system/media/audio/ringtones/Terminated.ogg \ - $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:system/media/audio/ringtones/TwirlAway.ogg \ - $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:system/media/audio/ringtones/VeryAlarmed.ogg \ - $(LOCAL_PATH)/newwavelabs/World.ogg:system/media/audio/ringtones/World.ogg \ - $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:system/media/audio/notifications/DearDeer.ogg \ - $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:system/media/audio/notifications/DontPanic.ogg \ - $(LOCAL_PATH)/newwavelabs/Highwire.ogg:system/media/audio/notifications/Highwire.ogg \ - $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:system/media/audio/notifications/KzurbSonar.ogg \ - $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:system/media/audio/notifications/OnTheHunt.ogg \ - $(LOCAL_PATH)/newwavelabs/Voila.ogg:system/media/audio/notifications/Voila.ogg \ - $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \ - $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg + $(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BentleyDubs.ogg \ + $(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/BirdLoop.ogg \ + $(LOCAL_PATH)/newwavelabs/CaribbeanIce.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CaribbeanIce.ogg \ + $(LOCAL_PATH)/newwavelabs/CurveBall.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CurveBall.ogg \ + $(LOCAL_PATH)/newwavelabs/EtherShake.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/EtherShake.ogg \ + $(LOCAL_PATH)/newwavelabs/FriendlyGhost.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/FriendlyGhost.ogg \ + $(LOCAL_PATH)/newwavelabs/GameOverGuitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/GameOverGuitar.ogg \ + $(LOCAL_PATH)/newwavelabs/Growl.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Growl.ogg \ + $(LOCAL_PATH)/newwavelabs/InsertCoin.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/InsertCoin.ogg \ + $(LOCAL_PATH)/newwavelabs/LoopyLounge.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoopyLounge.ogg \ + $(LOCAL_PATH)/newwavelabs/LoveFlute.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/LoveFlute.ogg \ + $(LOCAL_PATH)/newwavelabs/MidEvilJaunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MidEvilJaunt.ogg \ + $(LOCAL_PATH)/newwavelabs/MildlyAlarming.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/MildlyAlarming.ogg \ + $(LOCAL_PATH)/newwavelabs/NewPlayer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/NewPlayer.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises1.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises1.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises2.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises2.ogg \ + $(LOCAL_PATH)/newwavelabs/Noises3.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Noises3.ogg \ + $(LOCAL_PATH)/newwavelabs/OrganDub.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/OrganDub.ogg \ + $(LOCAL_PATH)/newwavelabs/RomancingTheTone.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/RomancingTheTone.ogg \ + $(LOCAL_PATH)/newwavelabs/SitarVsSitar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SitarVsSitar.ogg \ + $(LOCAL_PATH)/newwavelabs/SpringyJalopy.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/SpringyJalopy.ogg \ + $(LOCAL_PATH)/newwavelabs/Terminated.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/Terminated.ogg \ + $(LOCAL_PATH)/newwavelabs/TwirlAway.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/TwirlAway.ogg \ + $(LOCAL_PATH)/newwavelabs/VeryAlarmed.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/VeryAlarmed.ogg \ + $(LOCAL_PATH)/newwavelabs/World.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/World.ogg \ + $(LOCAL_PATH)/newwavelabs/DearDeer.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DearDeer.ogg \ + $(LOCAL_PATH)/newwavelabs/DontPanic.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/DontPanic.ogg \ + $(LOCAL_PATH)/newwavelabs/Highwire.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Highwire.ogg \ + $(LOCAL_PATH)/newwavelabs/KzurbSonar.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/KzurbSonar.ogg \ + $(LOCAL_PATH)/newwavelabs/OnTheHunt.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/OnTheHunt.ogg \ + $(LOCAL_PATH)/newwavelabs/Voila.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/notifications/Voila.ogg \ + $(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/CrazyDream.ogg \ + $(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ringtones/DreamTheme.ogg endif diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java index 235325ebaf06..c496cf75995e 100644 --- a/media/java/android/media/MediaItem2.java +++ b/media/java/android/media/MediaItem2.java @@ -40,9 +40,8 @@ import java.util.concurrent.Executor; * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> * for consistent behavior across all devices. * <p> - * @hide */ -public class MediaItem2 implements Parcelable { +public final class MediaItem2 implements Parcelable { private static final String TAG = "MediaItem2"; // intentionally less than long.MAX_VALUE. @@ -69,7 +68,6 @@ public class MediaItem2 implements Parcelable { } }; - // TODO: Use SessionPlayer2.UNKNOWN_TIME instead private static final long UNKNOWN_TIME = -1; private final long mStartPositionMs; diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 0057875ec3f4..fb18c3b67480 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -25,8 +25,10 @@ import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; +import android.graphics.SurfaceTexture; +import android.media.SubtitleController.Anchor; +import android.media.SubtitleTrack.RenderingWidget; import android.net.Uri; -import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -35,30 +37,19 @@ import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; -import android.os.Process; import android.os.PowerManager; +import android.os.Process; import android.os.SystemProperties; import android.provider.Settings; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import android.util.ArrayMap; import android.util.Log; import android.util.Pair; -import android.util.ArrayMap; import android.view.Surface; import android.view.SurfaceHolder; import android.widget.VideoView; -import android.graphics.SurfaceTexture; -import android.media.AudioManager; -import android.media.MediaDrm; -import android.media.MediaFormat; -import android.media.MediaTimeProvider; -import android.media.PlaybackParams; -import android.media.SubtitleController; -import android.media.SubtitleController.Anchor; -import android.media.SubtitleData; -import android.media.SubtitleTrack.RenderingWidget; -import android.media.SyncParams; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; @@ -72,7 +63,6 @@ import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.lang.Runnable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -2105,9 +2095,11 @@ public class MediaPlayer extends PlayerBase mOnInfoListener = null; mOnVideoSizeChangedListener = null; mOnTimedTextListener = null; - if (mTimeProvider != null) { - mTimeProvider.close(); - mTimeProvider = null; + synchronized (mTimeProviderLock) { + if (mTimeProvider != null) { + mTimeProvider.close(); + mTimeProvider = null; + } } synchronized(this) { mSubtitleDataListenerDisabled = false; @@ -2147,9 +2139,11 @@ public class MediaPlayer extends PlayerBase if (mSubtitleController != null) { mSubtitleController.reset(); } - if (mTimeProvider != null) { - mTimeProvider.close(); - mTimeProvider = null; + synchronized (mTimeProviderLock) { + if (mTimeProvider != null) { + mTimeProvider.close(); + mTimeProvider = null; + } } stayAwake(false); @@ -2790,12 +2784,17 @@ public class MediaPlayer extends PlayerBase synchronized (mIndexTrackPairs) { mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track)); } - Handler h = mTimeProvider.mEventHandler; - int what = TimeProvider.NOTIFY; - int arg1 = TimeProvider.NOTIFY_TRACK_DATA; - Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes()); - Message m = h.obtainMessage(what, arg1, 0, trackData); - h.sendMessage(m); + synchronized (mTimeProviderLock) { + if (mTimeProvider != null) { + Handler h = mTimeProvider.mEventHandler; + int what = TimeProvider.NOTIFY; + int arg1 = TimeProvider.NOTIFY_TRACK_DATA; + Pair<SubtitleTrack, byte[]> trackData = + Pair.create(track, contents.getBytes()); + Message m = h.obtainMessage(what, arg1, 0, trackData); + h.sendMessage(m); + } + } return MEDIA_INFO_EXTERNAL_METADATA_UPDATE; } @@ -3020,12 +3019,17 @@ public class MediaPlayer extends PlayerBase total += bytes; } } - Handler h = mTimeProvider.mEventHandler; - int what = TimeProvider.NOTIFY; - int arg1 = TimeProvider.NOTIFY_TRACK_DATA; - Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray()); - Message m = h.obtainMessage(what, arg1, 0, trackData); - h.sendMessage(m); + synchronized (mTimeProviderLock) { + if (mTimeProvider != null) { + Handler h = mTimeProvider.mEventHandler; + int what = TimeProvider.NOTIFY; + int arg1 = TimeProvider.NOTIFY_TRACK_DATA; + Pair<SubtitleTrack, byte[]> trackData = + Pair.create(track, bos.toByteArray()); + Message m = h.obtainMessage(what, arg1, 0, trackData); + h.sendMessage(m); + } + } return MEDIA_INFO_EXTERNAL_METADATA_UPDATE; } catch (Exception e) { Log.e(TAG, e.getMessage(), e); @@ -3308,14 +3312,17 @@ public class MediaPlayer extends PlayerBase private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000; private TimeProvider mTimeProvider; + private final Object mTimeProviderLock = new Object(); /** @hide */ @UnsupportedAppUsage public MediaTimeProvider getMediaTimeProvider() { - if (mTimeProvider == null) { - mTimeProvider = new TimeProvider(this); + synchronized (mTimeProviderLock) { + if (mTimeProvider == null) { + mTimeProvider = new TimeProvider(this); + } + return mTimeProvider; } - return mTimeProvider; } private class EventHandler extends Handler diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java index 4712cddf3522..1ee851f5a068 100644 --- a/media/java/android/media/MediaSession2.java +++ b/media/java/android/media/MediaSession2.java @@ -464,7 +464,21 @@ public class MediaSession2 implements AutoCloseable { if (mId == null) { mId = ""; } - return new MediaSession2(mContext, mId, mSessionActivity, mCallbackExecutor, mCallback); + MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity, + mCallbackExecutor, mCallback); + + // Notify framework about the newly create session after the constructor is finished. + // Otherwise, framework may access the session before the initialization is finished. + try { + MediaSessionManager manager = (MediaSessionManager) mContext.getSystemService( + Context.MEDIA_SESSION_SERVICE); + manager.notifySession2Created(session2.getSessionToken()); + } catch (Exception e) { + session2.close(); + throw e; + } + + return session2; } } diff --git a/core/java/android/hardware/display/BrightnessCorrection.aidl b/media/java/android/media/Session2Token.aidl index 3abe29cc0076..c5980e9e77fd 100644 --- a/core/java/android/hardware/display/BrightnessCorrection.aidl +++ b/media/java/android/media/Session2Token.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright 2019 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. @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.hardware.display; +package android.media; -parcelable BrightnessCorrection; +parcelable Session2Token; diff --git a/media/java/android/media/Session2Token.java b/media/java/android/media/Session2Token.java index 7642faae00c7..4634c6963675 100644 --- a/media/java/android/media/Session2Token.java +++ b/media/java/android/media/Session2Token.java @@ -102,7 +102,8 @@ public final class Session2Token implements Parcelable { private final ComponentName mComponentName; /** - * Constructor for the token. + * Constructor for the token with type {@link #TYPE_SESSION_SERVICE} or + * {@link #TYPE_LIBRARY_SERVICE}. * * @param context The context. * @param serviceComponent The component name of the service. @@ -119,7 +120,7 @@ public final class Session2Token implements Parcelable { final int uid = getUid(manager, serviceComponent.getPackageName()); // TODO: Uncomment below to stop hardcode type. - final int type = TYPE_SESSION; + final int type = TYPE_SESSION_SERVICE; // final int type; // if (isInterfaceDeclared(manager, MediaLibraryService2.SERVICE_INTERFACE, // serviceComponent)) { diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index d6c226f8b6d0..51148e2f1af4 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -17,6 +17,7 @@ package android.media.session; import android.content.ComponentName; import android.media.IRemoteVolumeController; +import android.media.Session2Token; import android.media.session.IActiveSessionsListener; import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; @@ -32,6 +33,7 @@ import android.view.KeyEvent; */ interface ISessionManager { ISession createSession(String packageName, in ISessionCallback cb, String tag, int userId); + void notifySession2Created(in Session2Token sessionToken); List<IBinder> getSessions(in ComponentName compName, int userId); void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent, boolean needWakeLock); diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 4221d66edb99..ef5cf008de88 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -26,6 +26,8 @@ import android.content.ComponentName; import android.content.Context; import android.media.AudioManager; import android.media.IRemoteVolumeController; +import android.media.MediaSession2; +import android.media.Session2Token; import android.media.browse.MediaBrowser; import android.os.Handler; import android.os.IBinder; @@ -102,6 +104,30 @@ public final class MediaSessionManager { } /** + * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is + * created. + * <p> + * Do not use this API directly, but create a new instance through the + * {@link MediaSession2.Builder} instead. + * + * @param token newly created session2 token + * @hide + */ + public void notifySession2Created(@NonNull Session2Token token) { + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + if (token.getType() != Session2Token.TYPE_SESSION) { + throw new IllegalArgumentException("token's type should be TYPE_SESSION"); + } + try { + mService.notifySession2Created(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** * Get a list of controllers for all ongoing sessions. The controllers will * be provided in priority order with the most important controller at index * 0. diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java index 56c415816558..f2db2da42527 100644 --- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java +++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java @@ -383,8 +383,7 @@ public class SmartActionsHelper { remoteAction.getIcon(), remoteAction.getTitle(), remoteAction.getActionIntent()) - .setSemanticAction( - Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) + .setContextual(true) .addExtras(Bundle.forPair(KEY_ACTION_TYPE, classification.getEntity(0))) .build(); actions.add(action); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 58feef55bd29..24d7011d9a35 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -35,7 +35,6 @@ import java.util.List; public class A2dpProfile implements LocalBluetoothProfile { private static final String TAG = "A2dpProfile"; - private static boolean V = false; private Context mContext; @@ -60,7 +59,6 @@ public class A2dpProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothA2dp) proxy; // We just bound to the service, so refresh the UI for any connected A2DP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -79,7 +77,6 @@ public class A2dpProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); mIsProfileReady=false; } } @@ -302,7 +299,7 @@ public class A2dpProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java index 988062de0a37..873dd1a643a4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java @@ -55,7 +55,6 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected"); mService = (BluetoothA2dpSink) proxy; // We just bound to the service, so refresh the UI for any connected A2DP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -74,7 +73,6 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected"); mIsProfileReady=false; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java index 62507f58426f..6b6df9b928e5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java @@ -58,7 +58,6 @@ public class HeadsetProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothHeadset) proxy; // We just bound to the service, so refresh the UI for any connected HFP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -80,7 +79,6 @@ public class HeadsetProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG,"Bluetooth service disconnected"); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index adb5ab34b5c1..577d98d93405 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -51,7 +51,6 @@ public class HearingAidProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothHearingAid) proxy; // We just bound to the service, so refresh the UI for any connected HearingAid devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -77,7 +76,6 @@ public class HearingAidProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); mIsProfileReady=false; } } @@ -234,7 +232,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java index 4879144a5994..c6bb2b304d6c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java @@ -59,7 +59,6 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected"); mService = (BluetoothHeadsetClient) proxy; // We just bound to the service, so refresh the UI for any connected HFP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -80,7 +79,6 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected"); mIsProfileReady=false; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java index 61e5b6b3e125..4dc050c6d5e3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java @@ -58,7 +58,6 @@ public class HidDeviceProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected :-), profile:" + profile); mService = (BluetoothHidDevice) proxy; // We just bound to the service, so refresh the UI for any connected HID devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -78,7 +77,6 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady = false; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java index 75d16db13efe..ca840d9a8ba4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java @@ -33,7 +33,6 @@ import java.util.List; */ public class HidProfile implements LocalBluetoothProfile { private static final String TAG = "HidProfile"; - private static boolean V = true; private BluetoothHidHost mService; private boolean mIsProfileReady; @@ -51,7 +50,6 @@ public class HidProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothHidHost) proxy; // We just bound to the service, so refresh the UI for any connected HID devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -70,7 +68,6 @@ public class HidProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); mIsProfileReady=false; } } @@ -186,7 +183,7 @@ public class HidProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_HOST, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java index 1e22f440b5f8..6acdcac86d92 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java @@ -59,7 +59,6 @@ public final class MapClientProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothMapClient) proxy; // We just bound to the service, so refresh the UI for any connected MAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -81,7 +80,6 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java index 758202412c93..28975d4b94c2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java @@ -58,7 +58,6 @@ public class MapProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected"); mService = (BluetoothMap) proxy; // We just bound to the service, so refresh the UI for any connected MAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -80,7 +79,6 @@ public class MapProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected"); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java index 7b811624a6f3..2d0a0902de24 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java @@ -34,7 +34,6 @@ import java.util.List; */ public class PanProfile implements LocalBluetoothProfile { private static final String TAG = "PanProfile"; - private static boolean V = true; private BluetoothPan mService; private boolean mIsProfileReady; @@ -53,13 +52,11 @@ public class PanProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothPan) proxy; mIsProfileReady=true; } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); mIsProfileReady=false; } } @@ -173,7 +170,7 @@ public class PanProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.PAN, mService); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java index 1f15601f2756..46723937a941 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java @@ -55,7 +55,6 @@ public final class PbapClientProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothPbapClient) proxy; // We just bound to the service, so refresh the UI for any connected PBAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -74,7 +73,6 @@ public final class PbapClientProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady = false; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java index adef0841cb2a..1b3c453be4ed 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java @@ -33,7 +33,6 @@ import com.android.settingslib.R; */ public class PbapServerProfile implements LocalBluetoothProfile { private static final String TAG = "PbapServerProfile"; - private static boolean V = true; private BluetoothPbap mService; private boolean mIsProfileReady; @@ -56,13 +55,11 @@ public class PbapServerProfile implements LocalBluetoothProfile { implements BluetoothPbap.ServiceListener { public void onServiceConnected(BluetoothPbap proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothPbap) proxy; mIsProfileReady=true; } public void onServiceDisconnected() { - if (V) Log.d(TAG,"Bluetooth service disconnected"); mIsProfileReady=false; } } @@ -142,7 +139,7 @@ public class PbapServerProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { mService.close(); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java index b4acc4810faf..ea2ebde3ff4c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java @@ -57,7 +57,6 @@ final class SapProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothSap) proxy; // We just bound to the service, so refresh the UI for any connected SAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -79,7 +78,6 @@ final class SapProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java index 570d351a8b71..27d624ab0b58 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java @@ -16,6 +16,8 @@ import com.android.systemui.Dependency; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; import java.util.Objects; import java.util.TimeZone; @@ -82,6 +84,24 @@ public class KeyguardClockSwitch extends RelativeLayout { } } }; + private final StatusBarStateController.StateListener mStateListener = + new StatusBarStateController.StateListener() { + @Override + public void onStateChanged(int newState) { + if (mBigClockContainer == null) { + return; + } + if (newState == StatusBarState.SHADE) { + if (mBigClockContainer.getVisibility() == View.VISIBLE) { + mBigClockContainer.setVisibility(View.INVISIBLE); + } + } else { + if (mBigClockContainer.getVisibility() == View.INVISIBLE) { + mBigClockContainer.setVisibility(View.VISIBLE); + } + } + } + }; public KeyguardClockSwitch(Context context) { this(context, null); @@ -104,12 +124,14 @@ public class KeyguardClockSwitch extends RelativeLayout { super.onAttachedToWindow(); Dependency.get(PluginManager.class).addPluginListener(mClockPluginListener, ClockPlugin.class); + Dependency.get(StatusBarStateController.class).addCallback(mStateListener); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); Dependency.get(PluginManager.class).removePluginListener(mClockPluginListener); + Dependency.get(StatusBarStateController.class).removeCallback(mStateListener); } /** @@ -238,4 +260,9 @@ public class KeyguardClockSwitch extends RelativeLayout { PluginListener getClockPluginListener() { return mClockPluginListener; } + + @VisibleForTesting (otherwise = VisibleForTesting.NONE) + StatusBarStateController.StateListener getStateListener() { + return mStateListener; + } } diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 3d2f838e4872..3cc9bb6f668f 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -278,6 +278,7 @@ public class Dependency extends SystemUI { Lazy<NotificationAlertingManager> mNotificationAlertingManager; @Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager; @Inject Lazy<AutoHideController> mAutoHideController; + @Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener; @Inject @Named(BG_LOOPER_NAME) Lazy<Looper> mBgLooper; @Inject @Named(BG_HANDLER_NAME) Lazy<Handler> mBgHandler; @Inject @Named(MAIN_HANDLER_NAME) Lazy<Handler> mMainHandler; @@ -450,6 +451,8 @@ public class Dependency extends SystemUI { mProviders.put(BubbleController.class, mBubbleController::get); mProviders.put(NotificationEntryManager.class, mNotificationEntryManager::get); mProviders.put(NotificationAlertingManager.class, mNotificationAlertingManager::get); + mProviders.put(ForegroundServiceNotificationListener.class, + mForegroundServiceNotificationListener::get); // TODO(b/118592525): to support multi-display , we start to add something which is // per-display, while others may be global. I think it's time to add diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java index 1ee1dcf74555..f324a05bafff 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java @@ -219,12 +219,6 @@ public abstract class DependencyBinder { /** */ @Binds - public abstract ForegroundServiceController provideForegroundService( - ForegroundServiceControllerImpl controllerImpl); - - /** - */ - @Binds public abstract PowerUI.WarningsUI provideWarningsUi(PowerNotificationWarnings controllerImpl); /** diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java index dac977ad5165..88e32cbeaa29 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java @@ -44,8 +44,6 @@ import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; -import com.android.systemui.statusbar.phone.ShadeController; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.NetworkController; @@ -141,12 +139,6 @@ public class DependencyProvider { @Singleton @Provides - public ShadeController provideShadeController(Context context) { - return SysUiServiceProvider.getComponent(context, StatusBar.class); - } - - @Singleton - @Provides public SensorPrivacyManager provideSensorPrivacyManager(Context context) { return context.getSystemService(SensorPrivacyManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java index ae6ee2af29fd..df0d7872bc61 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java @@ -15,65 +15,158 @@ package com.android.systemui; import android.annotation.Nullable; +import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.util.ArraySet; +import android.util.SparseArray; -public interface ForegroundServiceController { - /** - * @param sbn notification that was just posted - * @param importance - */ - void addNotification(StatusBarNotification sbn, int importance); +import com.android.internal.messages.nano.SystemMessageProto; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Tracks state of foreground services and notifications related to foreground services per user. + */ +@Singleton +public class ForegroundServiceController { + + private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>(); + private final Object mMutex = new Object(); + + @Inject + public ForegroundServiceController() { + } /** - * @param sbn notification that was just changed in some way - * @param newImportance + * @return true if this user has services missing notifications and therefore needs a + * disclosure notification. */ - void updateNotification(StatusBarNotification sbn, int newImportance); + public boolean isDisclosureNeededForUser(int userId) { + synchronized (mMutex) { + final ForegroundServicesUserState services = mUserServices.get(userId); + if (services == null) return false; + return services.isDisclosureNeeded(); + } + } /** - * @param sbn notification that was just canceled + * @return true if this user/pkg has a missing or custom layout notification and therefore needs + * a disclosure notification for system alert windows. */ - boolean removeNotification(StatusBarNotification sbn); + public boolean isSystemAlertWarningNeeded(int userId, String pkg) { + synchronized (mMutex) { + final ForegroundServicesUserState services = mUserServices.get(userId); + if (services == null) return false; + return services.getStandardLayoutKey(pkg) == null; + } + } /** - * @param userId - * @return true if this user has services missing notifications and therefore needs a - * disclosure notification. + * Returns the key of the foreground service from this package using the standard template, + * if one exists. */ - boolean isDungeonNeededForUser(int userId); + @Nullable + public String getStandardLayoutKey(int userId, String pkg) { + synchronized (mMutex) { + final ForegroundServicesUserState services = mUserServices.get(userId); + if (services == null) return null; + return services.getStandardLayoutKey(pkg); + } + } /** - * @param sbn - * @return true if sbn is the system-provided "dungeon" (list of running foreground services). + * Gets active app ops for this user and package */ - boolean isDungeonNotification(StatusBarNotification sbn); + @Nullable + public ArraySet<Integer> getAppOps(int userId, String pkg) { + synchronized (mMutex) { + final ForegroundServicesUserState services = mUserServices.get(userId); + if (services == null) { + return null; + } + return services.getFeatures(pkg); + } + } /** - * @return true if sbn is one of the window manager "drawing over other apps" notifications + * Records active app ops. App Ops are stored in FSC in addition to NotificationData in + * case they change before we have a notification to tag. */ - boolean isSystemAlertNotification(StatusBarNotification sbn); + public void onAppOpChanged(int code, int uid, String packageName, boolean active) { + int userId = UserHandle.getUserId(uid); + synchronized (mMutex) { + ForegroundServicesUserState userServices = mUserServices.get(userId); + if (userServices == null) { + userServices = new ForegroundServicesUserState(); + mUserServices.put(userId, userServices); + } + if (active) { + userServices.addOp(packageName, code); + } else { + userServices.removeOp(packageName, code); + } + } + } /** - * Returns the key of the foreground service from this package using the standard template, - * if one exists. + * Looks up the {@link ForegroundServicesUserState} for the given {@code userId}, then performs + * the given {@link UserStateUpdateCallback} on it. If no state exists for the user ID, creates + * a new one if {@code createIfNotFound} is true, then performs the update on the new state. + * If {@code createIfNotFound} is false, no update is performed. + * + * @return false if no user state was found and none was created; true otherwise. */ - @Nullable String getStandardLayoutKey(int userId, String pkg); + boolean updateUserState(int userId, + UserStateUpdateCallback updateCallback, + boolean createIfNotFound) { + synchronized (mMutex) { + ForegroundServicesUserState userState = mUserServices.get(userId); + if (userState == null) { + if (createIfNotFound) { + userState = new ForegroundServicesUserState(); + mUserServices.put(userId, userState); + } else { + return false; + } + } + return updateCallback.updateUserState(userState); + } + } /** - * @return true if this user/pkg has a missing or custom layout notification and therefore needs - * a disclosure notification for system alert windows. + * @return true if {@code sbn} is the system-provided disclosure notification containing the + * list of running foreground services. */ - boolean isSystemAlertWarningNeeded(int userId, String pkg); + public boolean isDisclosureNotification(StatusBarNotification sbn) { + return sbn.getId() == SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES + && sbn.getTag() == null + && sbn.getPackageName().equals("android"); + } /** - * Records active app ops. App Ops are stored in FSC in addition to NotificationData in - * case they change before we have a notification to tag. + * @return true if sbn is one of the window manager "drawing over other apps" notifications */ - void onAppOpChanged(int code, int uid, String packageName, boolean active); + public boolean isSystemAlertNotification(StatusBarNotification sbn) { + return sbn.getPackageName().equals("android") + && sbn.getTag() != null + && sbn.getTag().contains("AlertWindowNotification"); + } /** - * Gets active app ops for this user and package + * Callback provided to {@link #updateUserState(int, UserStateUpdateCallback, boolean)} + * to perform the update. */ - @Nullable ArraySet<Integer> getAppOps(int userId, String packageName); + interface UserStateUpdateCallback { + /** + * Perform update operations on the provided {@code userState}. + * + * @return true if the update succeeded. + */ + boolean updateUserState(ForegroundServicesUserState userState); + + /** Called if the state was not found and was not created. */ + default void userStateNotFound(int userId) { + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java deleted file mode 100644 index ae446ddc91ab..000000000000 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2017 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.systemui; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.os.Bundle; -import android.os.UserHandle; -import android.service.notification.StatusBarNotification; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; -import android.util.SparseArray; - -import com.android.internal.messages.nano.SystemMessageProto; - -import java.util.Arrays; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Foreground service controller, a/k/a Dianne's Dungeon. - */ -@Singleton -public class ForegroundServiceControllerImpl - implements ForegroundServiceController { - - // shelf life of foreground services before they go bad - public static final long FG_SERVICE_GRACE_MILLIS = 5000; - - private static final String TAG = "FgServiceController"; - private static final boolean DBG = false; - - private final Context mContext; - private final SparseArray<UserServices> mUserServices = new SparseArray<>(); - private final Object mMutex = new Object(); - - @Inject - public ForegroundServiceControllerImpl(Context context) { - mContext = context; - } - - @Override - public boolean isDungeonNeededForUser(int userId) { - synchronized (mMutex) { - final UserServices services = mUserServices.get(userId); - if (services == null) return false; - return services.isDungeonNeeded(); - } - } - - @Override - public boolean isSystemAlertWarningNeeded(int userId, String pkg) { - synchronized (mMutex) { - final UserServices services = mUserServices.get(userId); - if (services == null) return false; - return services.getStandardLayoutKey(pkg) == null; - } - } - - @Override - public String getStandardLayoutKey(int userId, String pkg) { - synchronized (mMutex) { - final UserServices services = mUserServices.get(userId); - if (services == null) return null; - return services.getStandardLayoutKey(pkg); - } - } - - @Override - public ArraySet<Integer> getAppOps(int userId, String pkg) { - synchronized (mMutex) { - final UserServices services = mUserServices.get(userId); - if (services == null) { - return null; - } - return services.getFeatures(pkg); - } - } - - @Override - public void onAppOpChanged(int code, int uid, String packageName, boolean active) { - int userId = UserHandle.getUserId(uid); - synchronized (mMutex) { - UserServices userServices = mUserServices.get(userId); - if (userServices == null) { - userServices = new UserServices(); - mUserServices.put(userId, userServices); - } - if (active) { - userServices.addOp(packageName, code); - } else { - userServices.removeOp(packageName, code); - } - } - } - - @Override - public void addNotification(StatusBarNotification sbn, int importance) { - updateNotification(sbn, importance); - } - - @Override - public boolean removeNotification(StatusBarNotification sbn) { - synchronized (mMutex) { - final UserServices userServices = mUserServices.get(sbn.getUserId()); - if (userServices == null) { - if (DBG) { - Log.w(TAG, String.format( - "user %d with no known notifications got removeNotification for %s", - sbn.getUserId(), sbn)); - } - return false; - } - if (isDungeonNotification(sbn)) { - // if you remove the dungeon entirely, we take that to mean there are - // no running services - userServices.setRunningServices(null, 0); - return true; - } else { - // this is safe to call on any notification, not just FLAG_FOREGROUND_SERVICE - return userServices.removeNotification(sbn.getPackageName(), sbn.getKey()); - } - } - } - - @Override - public void updateNotification(StatusBarNotification sbn, int newImportance) { - synchronized (mMutex) { - UserServices userServices = mUserServices.get(sbn.getUserId()); - if (userServices == null) { - userServices = new UserServices(); - mUserServices.put(sbn.getUserId(), userServices); - } - - if (isDungeonNotification(sbn)) { - final Bundle extras = sbn.getNotification().extras; - if (extras != null) { - final String[] svcs = extras.getStringArray(Notification.EXTRA_FOREGROUND_APPS); - userServices.setRunningServices(svcs, sbn.getNotification().when); - } - } else { - userServices.removeNotification(sbn.getPackageName(), sbn.getKey()); - if (0 != (sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE)) { - if (newImportance > NotificationManager.IMPORTANCE_MIN) { - userServices.addImportantNotification(sbn.getPackageName(), sbn.getKey()); - } - final Notification.Builder builder = Notification.Builder.recoverBuilder( - mContext, sbn.getNotification()); - if (builder.usesStandardHeader()) { - userServices.addStandardLayoutNotification( - sbn.getPackageName(), sbn.getKey()); - } - } - } - } - } - - @Override - public boolean isDungeonNotification(StatusBarNotification sbn) { - return sbn.getId() == SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES - && sbn.getTag() == null - && sbn.getPackageName().equals("android"); - } - - @Override - public boolean isSystemAlertNotification(StatusBarNotification sbn) { - return sbn.getPackageName().equals("android") - && sbn.getTag() != null - && sbn.getTag().contains("AlertWindowNotification"); - } - - /** - * Struct to track relevant packages and notifications for a userid's foreground services. - */ - private static class UserServices { - private String[] mRunning = null; - private long mServiceStartTime = 0; - // package -> sufficiently important posted notification keys - private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1); - // package -> standard layout posted notification keys - private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1); - - // package -> app ops - private ArrayMap<String, ArraySet<Integer>> mAppOps = new ArrayMap<>(1); - - public void setRunningServices(String[] pkgs, long serviceStartTime) { - mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null; - mServiceStartTime = serviceStartTime; - } - - public void addOp(String pkg, int op) { - if (mAppOps.get(pkg) == null) { - mAppOps.put(pkg, new ArraySet<>(3)); - } - mAppOps.get(pkg).add(op); - } - - public boolean removeOp(String pkg, int op) { - final boolean found; - final ArraySet<Integer> keys = mAppOps.get(pkg); - if (keys == null) { - found = false; - } else { - found = keys.remove(op); - if (keys.size() == 0) { - mAppOps.remove(pkg); - } - } - return found; - } - - public void addImportantNotification(String pkg, String key) { - addNotification(mImportantNotifications, pkg, key); - } - - public boolean removeImportantNotification(String pkg, String key) { - return removeNotification(mImportantNotifications, pkg, key); - } - - public void addStandardLayoutNotification(String pkg, String key) { - addNotification(mStandardLayoutNotifications, pkg, key); - } - - public boolean removeStandardLayoutNotification(String pkg, String key) { - return removeNotification(mStandardLayoutNotifications, pkg, key); - } - - public boolean removeNotification(String pkg, String key) { - boolean removed = false; - removed |= removeImportantNotification(pkg, key); - removed |= removeStandardLayoutNotification(pkg, key); - return removed; - } - - public void addNotification(ArrayMap<String, ArraySet<String>> map, String pkg, - String key) { - if (map.get(pkg) == null) { - map.put(pkg, new ArraySet<>()); - } - map.get(pkg).add(key); - } - - public boolean removeNotification(ArrayMap<String, ArraySet<String>> map, - String pkg, String key) { - final boolean found; - final ArraySet<String> keys = map.get(pkg); - if (keys == null) { - found = false; - } else { - found = keys.remove(key); - if (keys.size() == 0) { - map.remove(pkg); - } - } - return found; - } - - public boolean isDungeonNeeded() { - if (mRunning != null - && System.currentTimeMillis() - mServiceStartTime >= FG_SERVICE_GRACE_MILLIS) { - - for (String pkg : mRunning) { - final ArraySet<String> set = mImportantNotifications.get(pkg); - if (set == null || set.size() == 0) { - return true; - } - } - } - return false; - } - - public ArraySet<Integer> getFeatures(String pkg) { - return mAppOps.get(pkg); - } - - public String getStandardLayoutKey(String pkg) { - final ArraySet<String> set = mStandardLayoutNotifications.get(pkg); - if (set == null || set.size() == 0) { - return null; - } - return set.valueAt(0); - } - - @Override - public String toString() { - return "UserServices{" + - "mRunning=" + Arrays.toString(mRunning) + - ", mServiceStartTime=" + mServiceStartTime + - ", mImportantNotifications=" + mImportantNotifications + - ", mStandardLayoutNotifications=" + mStandardLayoutNotifications + - '}'; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java new file mode 100644 index 000000000000..b0b7e6c88984 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2018 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.systemui; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Bundle; +import android.service.notification.StatusBarNotification; +import android.util.Log; + +import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** Updates foreground service notification state in response to notification data events. */ +@Singleton +public class ForegroundServiceNotificationListener { + + private static final String TAG = "FgServiceController"; + private static final boolean DBG = false; + + private final Context mContext; + private final ForegroundServiceController mForegroundServiceController; + + @Inject + public ForegroundServiceNotificationListener(Context context, + ForegroundServiceController foregroundServiceController, + NotificationEntryManager notificationEntryManager) { + mContext = context; + mForegroundServiceController = foregroundServiceController; + notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onPendingEntryAdded(NotificationData.Entry entry) { + addNotification(entry.notification, entry.importance); + } + + @Override + public void onEntryUpdated(NotificationData.Entry entry) { + updateNotification(entry.notification, entry.importance); + } + + @Override + public void onEntryRemoved( + NotificationData.Entry entry, + NotificationVisibility visibility, + boolean removedByUser) { + removeNotification(entry.notification); + } + }); + } + + /** + * @param sbn notification that was just posted + */ + private void addNotification(StatusBarNotification sbn, int importance) { + updateNotification(sbn, importance); + } + + /** + * @param sbn notification that was just removed + */ + private void removeNotification(StatusBarNotification sbn) { + mForegroundServiceController.updateUserState( + sbn.getUserId(), + new ForegroundServiceController.UserStateUpdateCallback() { + @Override + public boolean updateUserState(ForegroundServicesUserState userState) { + if (mForegroundServiceController.isDisclosureNotification(sbn)) { + // if you remove the dungeon entirely, we take that to mean there are + // no running services + userState.setRunningServices(null, 0); + return true; + } else { + // this is safe to call on any notification, not just + // FLAG_FOREGROUND_SERVICE + return userState.removeNotification(sbn.getPackageName(), sbn.getKey()); + } + } + + @Override + public void userStateNotFound(int userId) { + if (DBG) { + Log.w(TAG, String.format( + "user %d with no known notifications got removeNotification " + + "for %s", + sbn.getUserId(), sbn)); + } + } + }, + false /* don't create */); + } + + /** + * @param sbn notification that was just changed in some way + */ + private void updateNotification(StatusBarNotification sbn, int newImportance) { + mForegroundServiceController.updateUserState( + sbn.getUserId(), + userState -> { + if (mForegroundServiceController.isDisclosureNotification(sbn)) { + final Bundle extras = sbn.getNotification().extras; + if (extras != null) { + final String[] svcs = extras.getStringArray( + Notification.EXTRA_FOREGROUND_APPS); + userState.setRunningServices(svcs, sbn.getNotification().when); + } + } else { + userState.removeNotification(sbn.getPackageName(), sbn.getKey()); + if (0 != (sbn.getNotification().flags + & Notification.FLAG_FOREGROUND_SERVICE)) { + if (newImportance > NotificationManager.IMPORTANCE_MIN) { + userState.addImportantNotification(sbn.getPackageName(), + sbn.getKey()); + } + final Notification.Builder builder = + Notification.Builder.recoverBuilder( + mContext, sbn.getNotification()); + if (builder.usesStandardHeader()) { + userState.addStandardLayoutNotification( + sbn.getPackageName(), sbn.getKey()); + } + } + } + return true; + }, + true /* create if not found */); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java new file mode 100644 index 000000000000..a8ae65490b28 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 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.systemui; + +import android.util.ArrayMap; +import android.util.ArraySet; + +import java.util.Arrays; + +/** + * Struct to track relevant packages and notifications for a userid's foreground services. + */ +class ForegroundServicesUserState { + // shelf life of foreground services before they go bad + private static final long FG_SERVICE_GRACE_MILLIS = 5000; + + private String[] mRunning = null; + private long mServiceStartTime = 0; + // package -> sufficiently important posted notification keys + private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1); + // package -> standard layout posted notification keys + private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1); + + // package -> app ops + private ArrayMap<String, ArraySet<Integer>> mAppOps = new ArrayMap<>(1); + + public void setRunningServices(String[] pkgs, long serviceStartTime) { + mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null; + mServiceStartTime = serviceStartTime; + } + + public void addOp(String pkg, int op) { + if (mAppOps.get(pkg) == null) { + mAppOps.put(pkg, new ArraySet<>(3)); + } + mAppOps.get(pkg).add(op); + } + + public boolean removeOp(String pkg, int op) { + final boolean found; + final ArraySet<Integer> keys = mAppOps.get(pkg); + if (keys == null) { + found = false; + } else { + found = keys.remove(op); + if (keys.size() == 0) { + mAppOps.remove(pkg); + } + } + return found; + } + + public void addImportantNotification(String pkg, String key) { + addNotification(mImportantNotifications, pkg, key); + } + + public boolean removeImportantNotification(String pkg, String key) { + return removeNotification(mImportantNotifications, pkg, key); + } + + public void addStandardLayoutNotification(String pkg, String key) { + addNotification(mStandardLayoutNotifications, pkg, key); + } + + public boolean removeStandardLayoutNotification(String pkg, String key) { + return removeNotification(mStandardLayoutNotifications, pkg, key); + } + + public boolean removeNotification(String pkg, String key) { + boolean removed = false; + removed |= removeImportantNotification(pkg, key); + removed |= removeStandardLayoutNotification(pkg, key); + return removed; + } + + public void addNotification(ArrayMap<String, ArraySet<String>> map, String pkg, + String key) { + if (map.get(pkg) == null) { + map.put(pkg, new ArraySet<>()); + } + map.get(pkg).add(key); + } + + public boolean removeNotification(ArrayMap<String, ArraySet<String>> map, + String pkg, String key) { + final boolean found; + final ArraySet<String> keys = map.get(pkg); + if (keys == null) { + found = false; + } else { + found = keys.remove(key); + if (keys.size() == 0) { + map.remove(pkg); + } + } + return found; + } + + public boolean isDisclosureNeeded() { + if (mRunning != null + && System.currentTimeMillis() - mServiceStartTime + >= FG_SERVICE_GRACE_MILLIS) { + + for (String pkg : mRunning) { + final ArraySet<String> set = mImportantNotifications.get(pkg); + if (set == null || set.size() == 0) { + return true; + } + } + } + return false; + } + + public ArraySet<Integer> getFeatures(String pkg) { + return mAppOps.get(pkg); + } + + public String getStandardLayoutKey(String pkg) { + final ArraySet<String> set = mStandardLayoutNotifications.get(pkg); + if (set == null || set.size() == 0) { + return null; + } + return set.valueAt(0); + } + + @Override + public String toString() { + return "UserServices{" + + "mRunning=" + Arrays.toString(mRunning) + + ", mServiceStartTime=" + mServiceStartTime + + ", mImportantNotifications=" + mImportantNotifications + + ", mStandardLayoutNotifications=" + mStandardLayoutNotifications + + '}'; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 073516e5cc18..5347a5cb16b6 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -51,6 +51,7 @@ import com.android.systemui.statusbar.phone.LockscreenWallpaper; import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ScrimState; +import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -208,6 +209,12 @@ public class SystemUIFactory { return true; } + @Singleton + @Provides + public ShadeController provideShadeController(Context context) { + return SysUiServiceProvider.getComponent(context, StatusBar.class); + } + @Module protected static class ContextHolder { private Context mContext; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 881aa18285ff..644723321103 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -33,8 +33,11 @@ import android.view.WindowManager; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarWindowController; import java.util.ArrayList; @@ -57,47 +60,31 @@ public class BubbleController { private static final String TAG = "BubbleController"; // Enables some subset of notifs to automatically become bubbles - public static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false; + private static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false; // When a bubble is dismissed, recreate it as a notification - public static final boolean DEBUG_DEMOTE_TO_NOTIF = false; + private static final boolean DEBUG_DEMOTE_TO_NOTIF = false; // Secure settings private static final String ENABLE_AUTO_BUBBLE_MESSAGES = "experiment_autobubble_messaging"; private static final String ENABLE_AUTO_BUBBLE_ONGOING = "experiment_autobubble_ongoing"; private static final String ENABLE_AUTO_BUBBLE_ALL = "experiment_autobubble_all"; - private Context mContext; - private BubbleDismissListener mDismissListener; + private final Context mContext; + private final NotificationEntryManager mNotificationEntryManager; private BubbleStateChangeListener mStateChangeListener; private BubbleExpandListener mExpandListener; - private Map<String, BubbleView> mBubbles = new HashMap<>(); + private final Map<String, BubbleView> mBubbles = new HashMap<>(); private BubbleStackView mStackView; - private Point mDisplaySize; + private final Point mDisplaySize; // Bubbles get added to the status bar view - @VisibleForTesting - protected StatusBarWindowController mStatusBarWindowController; + private final StatusBarWindowController mStatusBarWindowController; // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); /** - * Listener to find out about bubble / bubble stack dismissal events. - */ - public interface BubbleDismissListener { - /** - * Called when the entire stack of bubbles is dismissed by the user. - */ - void onStackDismissed(); - - /** - * Called when a specific bubble is dismissed by the user. - */ - void onBubbleDismissed(String key); - } - - /** * Listener to be notified when some states of the bubbles change. */ public interface BubbleStateChangeListener { @@ -123,17 +110,13 @@ public class BubbleController { @Inject public BubbleController(Context context, StatusBarWindowController statusBarWindowController) { mContext = context; + mNotificationEntryManager = Dependency.get(NotificationEntryManager.class); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mDisplaySize = new Point(); wm.getDefaultDisplay().getSize(mDisplaySize); mStatusBarWindowController = statusBarWindowController; - } - /** - * Set a listener to be notified of bubble dismissal events. - */ - public void setDismissListener(BubbleDismissListener listener) { - mDismissListener = listener; + mNotificationEntryManager.addNotificationEntryListener(mEntryListener); } /** @@ -180,7 +163,7 @@ public class BubbleController { /** * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack. */ - public void dismissStack() { + void dismissStack() { if (mStackView == null) { return; } @@ -190,9 +173,7 @@ public class BubbleController { for (String key: mBubbles.keySet()) { removeBubble(key); } - if (mDismissListener != null) { - mDismissListener.onStackDismissed(); - } + mNotificationEntryManager.updateNotifications(); updateBubblesShowing(); } @@ -238,18 +219,35 @@ public class BubbleController { /** * Removes the bubble associated with the {@param uri}. */ - public void removeBubble(String key) { + void removeBubble(String key) { BubbleView bv = mBubbles.get(key); if (mStackView != null && bv != null) { mStackView.removeBubble(bv); bv.getEntry().setBubbleDismissed(true); } - if (mDismissListener != null) { - mDismissListener.onBubbleDismissed(key); + + NotificationData.Entry entry = mNotificationEntryManager.getNotificationData().get(key); + if (entry != null) { + entry.setBubbleDismissed(true); + if (!DEBUG_DEMOTE_TO_NOTIF) { + mNotificationEntryManager.performRemoveNotification(entry.notification); + } } + mNotificationEntryManager.updateNotifications(); + updateBubblesShowing(); } + @SuppressWarnings("FieldCanBeLocal") + private final NotificationEntryListener mEntryListener = new NotificationEntryListener() { + @Override + public void onPendingEntryAdded(NotificationData.Entry entry) { + if (shouldAutoBubble(mContext, entry)) { + entry.setIsBubble(true); + } + } + }; + private void updateBubblesShowing() { boolean hasBubblesShowing = false; for (BubbleView bv : mBubbles.values()) { @@ -309,7 +307,7 @@ public class BubbleController { } @VisibleForTesting - public BubbleStackView getStackView() { + BubbleStackView getStackView() { return mStackView; } @@ -317,7 +315,7 @@ public class BubbleController { /** * Gets an appropriate starting point to position the bubble stack. */ - public static Point getStartPoint(int size, Point displaySize) { + private static Point getStartPoint(int size, Point displaySize) { final int x = displaySize.x - size + EDGE_OVERLAP; final int y = displaySize.y / 4; return new Point(x, y); @@ -326,7 +324,7 @@ public class BubbleController { /** * Gets an appropriate position for the bubble when the stack is expanded. */ - public static Point getExpandPoint(BubbleStackView view, int size, Point displaySize) { + static Point getExpandPoint(BubbleStackView view, int size, Point displaySize) { // Same place for now.. return new Point(EDGE_OVERLAP, size); } @@ -334,7 +332,7 @@ public class BubbleController { /** * Whether the notification should bubble or not. */ - public static boolean shouldAutoBubble(Context context, NotificationData.Entry entry) { + private static boolean shouldAutoBubble(Context context, NotificationData.Entry entry) { if (entry.isBubbleDismissed()) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 1bf101c00711..e59bc2a82c4c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -37,7 +37,6 @@ import android.media.session.PlaybackState; import android.os.Handler; import android.os.Trace; import android.os.UserHandle; -import android.service.notification.StatusBarNotification; import android.util.Log; import android.view.View; import android.widget.ImageView; @@ -157,15 +156,10 @@ public class NotificationMediaManager implements Dumpable { notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onEntryRemoved( - @Nullable Entry entry, - String key, - StatusBarNotification old, + Entry entry, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { - if (!lifetimeExtended) { - onNotificationRemoved(key); - } + onNotificationRemoved(entry.key); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 886d99eeff17..1ab9c5c2b4a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -254,13 +254,10 @@ public class NotificationRemoteInputManager implements Dumpable { @Override public void onEntryRemoved( @Nullable NotificationData.Entry entry, - String key, - StatusBarNotification old, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { if (removedByUser && entry != null) { - onPerformRemoveNotification(entry, key); + onPerformRemoveNotification(entry, entry.key); } } }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java index 7b42dd901d72..2bb0d5ce9161 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java @@ -20,7 +20,6 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORC import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP; -import android.annotation.Nullable; import android.app.Notification; import android.service.notification.StatusBarNotification; import android.util.Log; @@ -83,13 +82,10 @@ public class NotificationAlertingManager { @Override public void onEntryRemoved( - @Nullable NotificationData.Entry entry, - String key, - StatusBarNotification old, + NotificationData.Entry entry, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { - stopAlerting(key); + stopAlerting(entry.key); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java index 1d06ce031f2b..2f60f115ed53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java @@ -71,20 +71,14 @@ public interface NotificationEntryListener { * because the developer retracted it). * @param entry notification data entry that was removed. Null if no entry existed for the * removed key at the time of removal. - * @param key key of notification that was removed - * @param old StatusBarNotification of the notification before it was removed * @param visibility logging data related to the visibility of the notification at the time of * removal, if it was removed by a user action. Null if it was not removed by * a user action. - * @param lifetimeExtended true if something is artificially extending how long the notification * @param removedByUser true if the notification was removed by a user action */ default void onEntryRemoved( - @Nullable NotificationData.Entry entry, - String key, - StatusBarNotification old, + NotificationData.Entry entry, @Nullable NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index ab97e5e25ca1..6b5e70825d1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -15,13 +15,10 @@ */ package com.android.systemui.statusbar.notification; -import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF; - import android.annotation.Nullable; import android.app.Notification; import android.content.Context; import android.os.Handler; -import android.os.PowerManager; import android.os.UserHandle; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; @@ -34,7 +31,6 @@ import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.ForegroundServiceController; -import com.android.systemui.bubbles.BubbleController; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -65,8 +61,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback, NotificationUpdateHandler, - VisualStabilityManager.Callback, - BubbleController.BubbleDismissListener { + VisualStabilityManager.Callback { private static final String TAG = "NotificationEntryMgr"; protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -81,7 +76,6 @@ public class NotificationEntryManager implements Dependency.get(DeviceProvisionedController.class); private final ForegroundServiceController mForegroundServiceController = Dependency.get(ForegroundServiceController.class); - private final BubbleController mBubbleController = Dependency.get(BubbleController.class); // Lazily retrieved dependencies private NotificationRemoteInputManager mRemoteInputManager; @@ -91,9 +85,7 @@ public class NotificationEntryManager implements private Runnable mUpdateNotificationViewsCallback; private NotificationPresenter mPresenter; - protected PowerManager mPowerManager; private NotificationListenerService.RankingMap mLatestRankingMap; - protected HeadsUpManager mHeadsUpManager; protected NotificationData mNotificationData; protected NotificationListContainer mListContainer; @VisibleForTesting @@ -129,8 +121,6 @@ public class NotificationEntryManager implements public NotificationEntryManager(Context context) { mContext = context; - mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mBubbleController.setDismissListener(this /* bubbleEventListener */); mNotificationData = new NotificationData(); mDeferredNotificationViewUpdateHandler = new Handler(); } @@ -157,13 +147,18 @@ public class NotificationEntryManager implements return mNotificationRowBinder; } + // TODO: Remove this once we can always use a mocked row binder in our tests + @VisibleForTesting + void setRowBinder(NotificationRowBinder notificationRowBinder) { + mNotificationRowBinder = notificationRowBinder; + } + public void setUpWithPresenter(NotificationPresenter presenter, NotificationListContainer listContainer, HeadsUpManager headsUpManager) { mPresenter = presenter; mUpdateNotificationViewsCallback = mPresenter::updateNotificationViews; - mHeadsUpManager = headsUpManager; - mNotificationData.setHeadsUpManager(mHeadsUpManager); + mNotificationData.setHeadsUpManager(headsUpManager); mListContainer = listContainer; mDeviceProvisionedController.addCallback(mDeviceProvisionedListener); @@ -208,23 +203,6 @@ public class NotificationEntryManager implements n.getKey(), null, nv, false /* forceRemove */, true /* removedByUser */); } - @Override - public void onStackDismissed() { - updateNotifications(); - } - - @Override - public void onBubbleDismissed(String key) { - NotificationData.Entry entry = mNotificationData.get(key); - if (entry != null) { - entry.setBubbleDismissed(true); - if (!DEBUG_DEMOTE_TO_NOTIF) { - performRemoveNotification(entry.notification); - } - } - updateNotifications(); - } - private void abortExistingInflation(String key) { if (mPendingNotifications.containsKey(key)) { NotificationData.Entry entry = mPendingNotifications.get(key); @@ -252,21 +230,6 @@ public class NotificationEntryManager implements } } - private void addEntry(NotificationData.Entry shadeEntry) { - if (shadeEntry == null) { - return; - } - // Add the expanded view and icon. - mNotificationData.add(shadeEntry); - tagForeground(shadeEntry.notification); - updateNotifications(); - for (NotificationEntryListener listener : mNotificationEntryListeners) { - listener.onNotificationAdded(shadeEntry); - } - - maybeScheduleUpdateNotificationViews(shadeEntry); - } - private void maybeScheduleUpdateNotificationViews(NotificationData.Entry entry) { long audibleAlertTimeout = RECENTLY_ALERTED_THRESHOLD_MS - (System.currentTimeMillis() - entry.lastAudiblyAlertedMs); @@ -288,7 +251,13 @@ public class NotificationEntryManager implements for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onEntryInflated(entry, inflatedFlags); } - addEntry(entry); + mNotificationData.add(entry); + tagForeground(entry.notification); + updateNotifications(); + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onNotificationAdded(entry); + } + maybeScheduleUpdateNotificationViews(entry); } else { for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onEntryReinflated(entry); @@ -314,7 +283,6 @@ public class NotificationEntryManager implements abortExistingInflation(key); - StatusBarNotification old = null; boolean lifetimeExtended = false; if (entry != null) { @@ -339,8 +307,6 @@ public class NotificationEntryManager implements extender.setShouldManageLifetime(entry, false /* shouldManage */); } - mForegroundServiceController.removeNotification(entry.notification); - if (entry.rowExists()) { entry.removeRow(); mListContainer.cleanUpViewStateForEntry(entry); @@ -349,25 +315,15 @@ public class NotificationEntryManager implements // Let's remove the children if this was a summary handleGroupSummaryRemoved(key); - old = removeNotificationViews(key, ranking); - } - } - - for (NotificationEntryListener listener : mNotificationEntryListeners) { - listener.onEntryRemoved(entry, key, old, visibility, lifetimeExtended, removedByUser); - } - } + mNotificationData.remove(key, ranking); + updateNotifications(); + Dependency.get(LeakDetector.class).trackGarbage(entry); - private StatusBarNotification removeNotificationViews(String key, - NotificationListenerService.RankingMap ranking) { - NotificationData.Entry entry = mNotificationData.remove(key, ranking); - if (entry == null) { - Log.w(TAG, "removeNotification for unknown key: " + key); - return null; + for (NotificationEntryListener listener : mNotificationEntryListeners) { + listener.onEntryRemoved(entry, visibility, removedByUser); + } + } } - updateNotifications(); - Dependency.get(LeakDetector.class).trackGarbage(entry); - return entry.notification; } /** @@ -425,26 +381,6 @@ public class NotificationEntryManager implements } } - private NotificationData.Entry createNotificationEntry( - StatusBarNotification sbn, NotificationListenerService.Ranking ranking) - throws InflationException { - if (DEBUG) { - Log.d(TAG, "createNotificationEntry(notification=" + sbn + " " + ranking); - } - - NotificationData.Entry entry = new NotificationData.Entry(sbn, ranking); - if (BubbleController.shouldAutoBubble(getContext(), entry)) { - entry.setIsBubble(true); - } - - Dependency.get(LeakDetector.class).trackInstance(entry); - entry.createIcons(mContext, sbn); - // Construct the expanded view. - getRowBinder().inflateViews(entry, () -> performRemoveNotification(sbn), - mNotificationData.get(entry.key) != null); - return entry; - } - private void addNotificationInternal(StatusBarNotification notification, NotificationListenerService.RankingMap rankingMap) throws InflationException { String key = notification.getKey(); @@ -455,11 +391,15 @@ public class NotificationEntryManager implements mNotificationData.updateRanking(rankingMap); NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking(); rankingMap.getRanking(key, ranking); - NotificationData.Entry entry = createNotificationEntry(notification, ranking); - abortExistingInflation(key); - mForegroundServiceController.addNotification(notification, - mNotificationData.getImportance(key)); + NotificationData.Entry entry = new NotificationData.Entry(notification, ranking); + + Dependency.get(LeakDetector.class).trackInstance(entry); + // Construct the expanded view. + getRowBinder().inflateViews(entry, () -> performRemoveNotification(notification), + mNotificationData.get(entry.key) != null); + + abortExistingInflation(key); mPendingNotifications.put(key, entry); for (NotificationEntryListener listener : mNotificationEntryListeners) { @@ -518,21 +458,11 @@ public class NotificationEntryManager implements mNotificationData.update(entry, ranking, notification); - entry.updateIcons(mContext, notification); getRowBinder().inflateViews(entry, () -> performRemoveNotification(notification), mNotificationData.get(entry.key) != null); - mForegroundServiceController.updateNotification(notification, - mNotificationData.getImportance(key)); - updateNotifications(); - if (!notification.isClearable()) { - // The user may have performed a dismiss action on the notification, since it's - // not clearable we should snap it back. - mListContainer.snapViewIfNeeded(entry); - } - if (DEBUG) { // Is this for you? boolean isForCurrentUser = Dependency.get(KeyguardEnvironment.class) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java index 5e99c388655f..700382a103b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java @@ -117,8 +117,8 @@ public class NotificationFilter { return true; } - if (getFsc().isDungeonNotification(sbn) - && !getFsc().isDungeonNeededForUser(sbn.getUserId())) { + if (getFsc().isDisclosureNotification(sbn) + && !getFsc().isDisclosureNeededForUser(sbn.getUserId())) { // this is a foreground-service disclosure for a user that does not need to show one return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationRowBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationRowBinder.java index 0bde99b3c114..058efca51b21 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationRowBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationRowBinder.java @@ -125,17 +125,22 @@ public class NotificationRowBinder { /** * Inflates the views for the given entry (possibly asynchronously). */ - public void inflateViews(NotificationData.Entry entry, Runnable onDismissRunnable, - boolean isUpdate) { + public void inflateViews( + NotificationData.Entry entry, + Runnable onDismissRunnable, + boolean isUpdate) + throws InflationException { ViewGroup parent = mListContainer.getViewParentForNotification(entry); PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, entry.notification.getUser().getIdentifier()); final StatusBarNotification sbn = entry.notification; if (entry.rowExists()) { + entry.updateIcons(mContext, sbn); entry.reset(); updateNotification(entry, pmUser, sbn, entry.getRow(), isUpdate); } else { + entry.createIcons(mContext, sbn); new RowInflaterTask().inflate(mContext, parent, entry, row -> { bindRow(entry, pmUser, sbn, row, onDismissRunnable); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index 610d3003f0e9..43048a2c087e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -15,7 +15,6 @@ */ package com.android.systemui.statusbar.notification.logging; -import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.RemoteException; @@ -168,14 +167,11 @@ public class NotificationLogger implements StateListener { entryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onEntryRemoved( - @Nullable NotificationData.Entry entry, - String key, - StatusBarNotification old, + NotificationData.Entry entry, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { - if (removedByUser && visibility != null && entry != null) { - logNotificationClear(key, entry.notification, visibility); + if (removedByUser && visibility != null) { + logNotificationClear(entry.key, entry.notification, visibility); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java index f0a26536d7b8..1d5b9cce099d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java @@ -16,8 +16,7 @@ package com.android.systemui.statusbar.notification.stack; -import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator - .ExpandAnimationParameters; +import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import android.view.View; import android.view.ViewGroup; @@ -113,13 +112,6 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange void setMaxDisplayedNotifications(int maxNotifications); /** - * Handle snapping a non-dismissable row back if the user tried to dismiss it. - * - * @param entry the entry whose row needs to snap back - */ - void snapViewIfNeeded(NotificationData.Entry entry); - - /** * Get the view parent for a notification entry. For example, NotificationStackScrollLayout. * * @param entry entry to get the view parent for diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 8deb7d5e8456..1248cbff5e1a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -97,6 +97,7 @@ import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.ShadeViewRefactor; @@ -517,6 +518,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mLowPriorityBeforeSpeedBump = "1".equals(newValue); } }, LOW_PRIORITY); + + mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { + @Override + public void onEntryUpdated(NotificationData.Entry entry) { + if (!entry.notification.isClearable()) { + // The user may have performed a dismiss action on the notification, since it's + // not clearable we should snap it back. + snapViewIfNeeded(entry); + } + } + }); } @Override @@ -1538,9 +1550,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd true /* isDismissAll */); } - @Override @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - public void snapViewIfNeeded(NotificationData.Entry entry) { + private void snapViewIfNeeded(NotificationData.Entry entry) { ExpandableNotificationRow child = entry.getRow(); boolean animate = mIsExpanded || isPinnedHeadsUp(child); // If the child is showing the notification menu snap to that diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java index f1d9549b9284..975aee51228b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java @@ -189,10 +189,13 @@ class NotificationSwipeHelper extends SwipeHelper boolean isFastNonDismissGesture = gestureFastEnough && !gestureTowardsMenu && !isDismissGesture; boolean isMenuRevealingGestureAwayFromMenu = slowSwipedFarEnough || isFastNonDismissGesture; - if (isNonDismissGestureTowardsMenu - || (!isFalseGesture(ev) && isMenuRevealingGestureAwayFromMenu)) { + int menuSnapTarget = menuRow.getMenuSnapTarget(); + boolean isNonFalseMenuRevealingGesture = + !isFalseGesture(ev) && isMenuRevealingGestureAwayFromMenu; + if ((isNonDismissGestureTowardsMenu || isNonFalseMenuRevealingGesture) + && menuSnapTarget != 0) { // Menu has not been snapped to previously and this is menu revealing gesture - snapOpen(animView, menuRow.getMenuSnapTarget(), velocity); + snapOpen(animView, menuSnapTarget, velocity); menuRow.onSnapOpen(); } else if (isDismissGesture(ev) && !gestureTowardsMenu) { dismiss(animView, velocity); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index 3839ed5d5d88..af3257ae423e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -220,15 +220,12 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis @Override public void onEntryRemoved( @Nullable Entry entry, - String key, - StatusBarNotification old, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { // Removes any alerts pending on this entry. Note that this will not stop any inflation // tasks started by a transfer, so this should only be used as clean-up for when // inflation is stopped and the pending alert no longer needs to happen. - mPendingAlerts.remove(key); + mPendingAlerts.remove(entry.key); } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 7b7bcb448022..fb3157a128d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -43,6 +43,7 @@ import com.android.internal.widget.MessagingGroup; import com.android.internal.widget.MessagingMessage; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; +import com.android.systemui.ForegroundServiceNotificationListener; import com.android.systemui.InitController; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; @@ -195,14 +196,10 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, @Override public void onEntryRemoved( @Nullable Entry entry, - String key, - StatusBarNotification old, NotificationVisibility visibility, - boolean lifetimeExtended, boolean removedByUser) { - if (!lifetimeExtended) { - StatusBarNotificationPresenter.this.onNotificationRemoved(key, old); - } + StatusBarNotificationPresenter.this.onNotificationRemoved( + entry.key, entry.notification); if (removedByUser) { maybeEndAmbientPulse(); } @@ -228,6 +225,10 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, mVisualStabilityManager.setUpWithPresenter(this); gutsManager.setUpWithPresenter(this, notifListContainer, mCheckSaveListener, mOnSettingsClickListener); + // ForegroundServiceControllerListener adds its listener in its constructor + // but we need to request it here in order for it to be instantiated. + // TODO: figure out how to do this correctly once Dependency.get() is gone. + Dependency.get(ForegroundServiceNotificationListener.class); onUserSwitched(mLockscreenUserManager.getCurrentUserId()); }); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index 415060244243..1844df5c070a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -35,6 +35,8 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.text.TextPaint; import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextClock; @@ -42,6 +44,8 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; import org.junit.Before; import org.junit.Test; @@ -60,6 +64,7 @@ import org.mockito.MockitoAnnotations; public class KeyguardClockSwitchTest extends SysuiTestCase { private PluginManager mPluginManager; private FrameLayout mClockContainer; + private StatusBarStateController.StateListener mStateListener; @Mock TextClock mClockView; @@ -75,6 +80,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase { mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view); MockitoAnnotations.initMocks(this); when(mClockView.getPaint()).thenReturn(mock(TextPaint.class)); + mStateListener = mKeyguardClockSwitch.getStateListener(); } @Test @@ -272,4 +278,28 @@ public class KeyguardClockSwitchTest extends SysuiTestCase { verify(plugin).setStyle(style); } + + @Test + public void onStateChanged_InvisibleInShade() { + // GIVEN that the big clock container is visible + ViewGroup container = mock(ViewGroup.class); + when(container.getVisibility()).thenReturn(View.VISIBLE); + mKeyguardClockSwitch.setBigClockContainer(container); + // WHEN transitioned to SHADE state + mStateListener.onStateChanged(StatusBarState.SHADE); + // THEN the container is invisible. + verify(container).setVisibility(View.INVISIBLE); + } + + @Test + public void onStateChanged_VisibleInKeyguard() { + // GIVEN that the big clock container is invisible + ViewGroup container = mock(ViewGroup.class); + when(container.getVisibility()).thenReturn(View.INVISIBLE); + mKeyguardClockSwitch.setBigClockContainer(container); + // WHEN transitioned to KEYGUARD state + mStateListener.onStateChanged(StatusBarState.KEYGUARD); + // THEN the container is visible. + verify(container).setVisibility(View.VISIBLE); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java index f278a17d0637..f8912bcca302 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java @@ -22,6 +22,7 @@ import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.UserIdInt; @@ -35,197 +36,95 @@ import android.support.test.runner.AndroidJUnit4; import android.widget.RemoteViews; import com.android.internal.messages.nano.SystemMessageProto; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; @SmallTest @RunWith(AndroidJUnit4.class) public class ForegroundServiceControllerTest extends SysuiTestCase { - public static @UserIdInt int USERID_ONE = 10; // UserManagerService.MIN_USER_ID; - public static @UserIdInt int USERID_TWO = USERID_ONE + 1; + @UserIdInt private static final int USERID_ONE = 10; // UserManagerService.MIN_USER_ID; + @UserIdInt private static final int USERID_TWO = USERID_ONE + 1; - private ForegroundServiceController fsc; + private ForegroundServiceController mFsc; + private ForegroundServiceNotificationListener mListener; + private NotificationEntryListener mEntryListener; @Before public void setUp() throws Exception { - fsc = new ForegroundServiceControllerImpl(mContext); - } - - @Test - public void testNotificationCRUD_dungeon() { - StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, "com.example.app1"); - StatusBarNotification sbn_user2_app2_fg = makeMockFgSBN(USERID_TWO, "com.example.app2"); - StatusBarNotification sbn_user1_app3_fg = makeMockFgSBN(USERID_ONE, "com.example.app3"); - StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1", - 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - StatusBarNotification sbn_user2_app1 = makeMockSBN(USERID_TWO, "com.example.app1", - 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - - assertFalse(fsc.removeNotification(sbn_user1_app3_fg)); - assertFalse(fsc.removeNotification(sbn_user2_app2_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); - fsc.addNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_DEFAULT); - fsc.addNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_DEFAULT); - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); - fsc.addNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_DEFAULT); - - // these are never added to the tracker - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.updateNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); - fsc.updateNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_DEFAULT); - // should still not be there - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.updateNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_DEFAULT); - fsc.updateNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_DEFAULT); - fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); - - assertTrue(fsc.removeNotification(sbn_user1_app3_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app3_fg)); - - assertTrue(fsc.removeNotification(sbn_user2_app2_fg)); - assertFalse(fsc.removeNotification(sbn_user2_app2_fg)); - - assertTrue(fsc.removeNotification(sbn_user1_app1_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1_fg)); - - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - } - - @Test - public void testNotificationCRUD_stdLayout() { - StatusBarNotification sbn_user1_app1_fg = - makeMockFgSBN(USERID_ONE, "com.example.app1", 0, true); - StatusBarNotification sbn_user2_app2_fg = - makeMockFgSBN(USERID_TWO, "com.example.app2", 1, true); - StatusBarNotification sbn_user1_app3_fg = - makeMockFgSBN(USERID_ONE, "com.example.app3", 2, true); - StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1", - 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - StatusBarNotification sbn_user2_app1 = makeMockSBN(USERID_TWO, "com.example.app1", - 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - - assertFalse(fsc.removeNotification(sbn_user1_app3_fg)); - assertFalse(fsc.removeNotification(sbn_user2_app2_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); - fsc.addNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN); - fsc.addNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN); - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); - fsc.addNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN); - - // these are never added to the tracker - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.updateNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); - fsc.updateNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN); - // should still not be there - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); - - fsc.updateNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN); - fsc.updateNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN); - fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); - - assertTrue(fsc.removeNotification(sbn_user1_app3_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app3_fg)); - - assertTrue(fsc.removeNotification(sbn_user2_app2_fg)); - assertFalse(fsc.removeNotification(sbn_user2_app2_fg)); - - assertTrue(fsc.removeNotification(sbn_user1_app1_fg)); - assertFalse(fsc.removeNotification(sbn_user1_app1_fg)); - - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.removeNotification(sbn_user2_app1)); + mFsc = new ForegroundServiceController(); + NotificationEntryManager notificationEntryManager = mock(NotificationEntryManager.class); + mListener = new ForegroundServiceNotificationListener( + mContext, mFsc, notificationEntryManager); + ArgumentCaptor<NotificationEntryListener> entryListenerCaptor = + ArgumentCaptor.forClass(NotificationEntryListener.class); + verify(notificationEntryManager).addNotificationEntryListener( + entryListenerCaptor.capture()); + mEntryListener = entryListenerCaptor.getValue(); } @Test public void testAppOpsCRUD() { // no crash on remove that doesn't exist - fsc.onAppOpChanged(9, 1000, "pkg1", false); - assertNull(fsc.getAppOps(0, "pkg1")); + mFsc.onAppOpChanged(9, 1000, "pkg1", false); + assertNull(mFsc.getAppOps(0, "pkg1")); // multiuser & multipackage - fsc.onAppOpChanged(8, 50, "pkg1", true); - fsc.onAppOpChanged(1, 60, "pkg3", true); - fsc.onAppOpChanged(7, 500000, "pkg2", true); + mFsc.onAppOpChanged(8, 50, "pkg1", true); + mFsc.onAppOpChanged(1, 60, "pkg3", true); + mFsc.onAppOpChanged(7, 500000, "pkg2", true); - assertEquals(1, fsc.getAppOps(0, "pkg1").size()); - assertTrue(fsc.getAppOps(0, "pkg1").contains(8)); + assertEquals(1, mFsc.getAppOps(0, "pkg1").size()); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); - assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); - assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); + assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); + assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); - assertEquals(1, fsc.getAppOps(0, "pkg3").size()); - assertTrue(fsc.getAppOps(0, "pkg3").contains(1)); + assertEquals(1, mFsc.getAppOps(0, "pkg3").size()); + assertTrue(mFsc.getAppOps(0, "pkg3").contains(1)); // multiple ops for the same package - fsc.onAppOpChanged(9, 50, "pkg1", true); - fsc.onAppOpChanged(5, 50, "pkg1", true); + mFsc.onAppOpChanged(9, 50, "pkg1", true); + mFsc.onAppOpChanged(5, 50, "pkg1", true); - assertEquals(3, fsc.getAppOps(0, "pkg1").size()); - assertTrue(fsc.getAppOps(0, "pkg1").contains(8)); - assertTrue(fsc.getAppOps(0, "pkg1").contains(9)); - assertTrue(fsc.getAppOps(0, "pkg1").contains(5)); + assertEquals(3, mFsc.getAppOps(0, "pkg1").size()); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(9)); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(5)); - assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); - assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); + assertEquals(1, mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size()); + assertTrue(mFsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7)); // remove one of the multiples - fsc.onAppOpChanged(9, 50, "pkg1", false); - assertEquals(2, fsc.getAppOps(0, "pkg1").size()); - assertTrue(fsc.getAppOps(0, "pkg1").contains(8)); - assertTrue(fsc.getAppOps(0, "pkg1").contains(5)); + mFsc.onAppOpChanged(9, 50, "pkg1", false); + assertEquals(2, mFsc.getAppOps(0, "pkg1").size()); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(8)); + assertTrue(mFsc.getAppOps(0, "pkg1").contains(5)); // remove last op - fsc.onAppOpChanged(1, 60, "pkg3", false); - assertNull(fsc.getAppOps(0, "pkg3")); + mFsc.onAppOpChanged(1, 60, "pkg3", false); + assertNull(mFsc.getAppOps(0, "pkg3")); } @Test - public void testDungeonPredicate() { + public void testDisclosurePredicate() { StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1", 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - StatusBarNotification sbn_user1_dungeon = makeMockSBN(USERID_ONE, "android", + StatusBarNotification sbn_user1_disclosure = makeMockSBN(USERID_ONE, "android", SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES, null, Notification.FLAG_NO_CLEAR); - assertTrue(fsc.isDungeonNotification(sbn_user1_dungeon)); - assertFalse(fsc.isDungeonNotification(sbn_user1_app1)); + assertTrue(mFsc.isDisclosureNotification(sbn_user1_disclosure)); + assertFalse(mFsc.isDisclosureNotification(sbn_user1_app1)); } @Test - public void testDungeonCRUD() { - StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1", - 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - StatusBarNotification sbn_user1_dungeon = makeMockSBN(USERID_ONE, "android", - SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICES, - null, Notification.FLAG_NO_CLEAR); - - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); - fsc.addNotification(sbn_user1_dungeon, NotificationManager.IMPORTANCE_DEFAULT); - - fsc.removeNotification(sbn_user1_dungeon); - assertFalse(fsc.removeNotification(sbn_user1_app1)); - } - - @Test - public void testNeedsDungeonAfterRemovingUnrelatedNotification() { + public void testNeedsDisclosureAfterRemovingUnrelatedNotification() { final String PKG1 = "com.example.app100"; StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, @@ -233,21 +132,21 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1); // first add a normal notification - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // nothing required yet - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // now the app starts a fg service - fsc.addNotification(makeMockDungeon(USERID_ONE, new String[]{ PKG1 }), + entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! // add the fg notification - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); // app1 has got it covered + entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered // remove the boring notification - fsc.removeNotification(sbn_user1_app1); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); // app1 has STILL got it covered - assertTrue(fsc.removeNotification(sbn_user1_app1_fg)); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! + entryRemoved(sbn_user1_app1); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has STILL got it covered + entryRemoved(sbn_user1_app1_fg); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! } @Test @@ -257,115 +156,117 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // no services are "running" - fsc.addNotification(makeMockDungeon(USERID_ONE, null), + entryAdded(makeMockDisclosure(USERID_ONE, null), NotificationManager.IMPORTANCE_DEFAULT); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); - fsc.updateNotification(makeMockDungeon(USERID_ONE, new String[]{PKG1}), + entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); // switch to different package - fsc.updateNotification(makeMockDungeon(USERID_ONE, new String[]{PKG2}), + entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); - fsc.updateNotification(makeMockDungeon(USERID_TWO, new String[]{PKG1}), + entryUpdated(makeMockDisclosure(USERID_TWO, new String[]{PKG1}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); - assertTrue(fsc.isDungeonNeededForUser(USERID_TWO)); // finally user2 needs one too + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); // finally user2 needs one too - fsc.updateNotification(makeMockDungeon(USERID_ONE, new String[]{PKG2, PKG1}), + entryUpdated(makeMockDisclosure(USERID_ONE, new String[]{PKG2, PKG1}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); - assertTrue(fsc.isDungeonNeededForUser(USERID_TWO)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); - fsc.removeNotification(makeMockDungeon(USERID_ONE, null /*unused*/)); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); - assertTrue(fsc.isDungeonNeededForUser(USERID_TWO)); + entryRemoved(makeMockDisclosure(USERID_ONE, null /*unused*/)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_TWO)); - fsc.removeNotification(makeMockDungeon(USERID_TWO, null /*unused*/)); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryRemoved(makeMockDisclosure(USERID_TWO, null /*unused*/)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); } @Test - public void testDungeonBasic() { + public void testDisclosureBasic() { final String PKG1 = "com.example.app0"; StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, PKG1, 5000, "monkeys", Notification.FLAG_AUTO_CANCEL); StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1); - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // not fg - fsc.addNotification(makeMockDungeon(USERID_ONE, new String[]{ PKG1 }), + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // not fg + entryAdded(makeMockDisclosure(USERID_ONE, new String[]{PKG1}), NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); // app1 has got it covered - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! + entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // app1 has got it covered + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); // let's take out the other notification and see what happens. - fsc.removeNotification(sbn_user1_app1); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); // still covered by sbn_user1_app1_fg - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryRemoved(sbn_user1_app1); + assertFalse( + mFsc.isDisclosureNeededForUser(USERID_ONE)); // still covered by sbn_user1_app1_fg + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1); sbn_user1_app1_fg_sneaky.getNotification().flags = 0; - fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryUpdated(sbn_user1_app1_fg_sneaky, + NotificationManager.IMPORTANCE_DEFAULT); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); // ok, ok, we'll put it back sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; - fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); - assertTrue(fsc.removeNotification(sbn_user1_app1_fg_sneaky)); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); // should be required! - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryRemoved(sbn_user1_app1_fg_sneaky); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // should be required! + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); // now let's test an upgrade - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; - fsc.updateNotification(sbn_user1_app1, + entryUpdated(sbn_user1_app1, NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); // remove it, make sure we're out of compliance again - assertTrue(fsc.removeNotification(sbn_user1_app1)); // was fg, should return true - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); + entryRemoved(sbn_user1_app1); // was fg, should return true + entryRemoved(sbn_user1_app1); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); // importance upgrade - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); - assertTrue(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); + assertTrue(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; - fsc.updateNotification(sbn_user1_app1_fg, + entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification // finally, let's turn off the service - fsc.addNotification(makeMockDungeon(USERID_ONE, null), + entryAdded(makeMockDisclosure(USERID_ONE, null), NotificationManager.IMPORTANCE_DEFAULT); - assertFalse(fsc.isDungeonNeededForUser(USERID_ONE)); - assertFalse(fsc.isDungeonNeededForUser(USERID_TWO)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_ONE)); + assertFalse(mFsc.isDisclosureNeededForUser(USERID_TWO)); } @Test @@ -375,8 +276,8 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { StatusBarNotification sbn_user1_overlay = makeMockSBN(USERID_ONE, "android", 0, "AlertWindowNotification", Notification.FLAG_NO_CLEAR); - assertTrue(fsc.isSystemAlertNotification(sbn_user1_overlay)); - assertFalse(fsc.isSystemAlertNotification(sbn_user1_app1)); + assertTrue(mFsc.isSystemAlertNotification(sbn_user1_overlay)); + assertFalse(mFsc.isSystemAlertNotification(sbn_user1_app1)); } @Test @@ -386,54 +287,54 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { StatusBarNotification sbn_user1_app1 = makeMockFgSBN(USERID_ONE, PKG1, 0, true); sbn_user1_app1.getNotification().flags = 0; StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1, 1, true); - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! - fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg")); + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! + entryAdded(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg")); // let's take out the non-fg notification and see what happens. - fsc.removeNotification(sbn_user1_app1); + entryRemoved(sbn_user1_app1); // still covered by sbn_user1_app1_fg - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg")); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg")); // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, true); sbn_user1_app1_fg_sneaky.getNotification().flags = 0; - fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN); - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything")); + entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN); + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything")); // ok, ok, we'll put it back sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; - fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever")); + entryUpdated(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever")); - assertTrue(fsc.removeNotification(sbn_user1_app1_fg_sneaky)); - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "a")); + entryRemoved(sbn_user1_app1_fg_sneaky); + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "a")); // let's try a custom layout sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, false); - fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN); - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything")); + entryUpdated(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN); + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required! + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "anything")); // now let's test an upgrade (non fg to fg) - fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "b")); + entryAdded(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, "b")); sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; - fsc.updateNotification(sbn_user1_app1, + entryUpdated(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // this is now a fg notification - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1)); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1)); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // remove it, make sure we're out of compliance again - assertTrue(fsc.removeNotification(sbn_user1_app1)); // was fg, should return true - assertFalse(fsc.removeNotification(sbn_user1_app1)); - assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1)); - assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); + entryRemoved(sbn_user1_app1); // was fg, should return true + entryRemoved(sbn_user1_app1); + assertFalse(mFsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1)); + assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); } private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag, @@ -475,7 +376,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { return makeMockSBN(userid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE); } - private StatusBarNotification makeMockDungeon(int userid, String[] pkgs) { + private StatusBarNotification makeMockDisclosure(int userid, String[] pkgs) { final Notification n = mock(Notification.class); n.flags = Notification.FLAG_ONGOING_EVENT; final Bundle extras = new Bundle(); @@ -488,4 +389,21 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { sbn.getNotification().extras = extras; return sbn; } + + private void entryRemoved(StatusBarNotification notification) { + mEntryListener.onEntryRemoved(new NotificationData.Entry(notification), + null, false); + } + + private void entryAdded(StatusBarNotification notification, int importance) { + NotificationData.Entry entry = new NotificationData.Entry(notification); + entry.importance = importance; + mEntryListener.onPendingEntryAdded(entry); + } + + private void entryUpdated(StatusBarNotification notification, int importance) { + NotificationData.Entry entry = new NotificationData.Entry(notification); + entry.importance = importance; + mEntryListener.onEntryUpdated(entry); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 8f2b2d065f72..31df4a3fc766 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -18,6 +18,10 @@ package com.android.systemui.bubbles; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.content.Context; @@ -29,6 +33,9 @@ import android.widget.FrameLayout; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationTestHelper; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.StatusBarWindowController; @@ -36,6 +43,8 @@ import com.android.systemui.statusbar.phone.StatusBarWindowController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -45,6 +54,8 @@ import org.mockito.MockitoAnnotations; public class BubbleControllerTest extends SysuiTestCase { @Mock + private NotificationEntryManager mNotificationEntryManager; + @Mock private WindowManager mWindowManager; @Mock private IActivityManager mActivityManager; @@ -52,17 +63,23 @@ public class BubbleControllerTest extends SysuiTestCase { private DozeParameters mDozeParameters; @Mock private FrameLayout mStatusBarView; + @Captor + private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor; private TestableBubbleController mBubbleController; private StatusBarWindowController mStatusBarWindowController; + private NotificationEntryListener mEntryListener; private NotificationTestHelper mNotificationTestHelper; private ExpandableNotificationRow mRow; private ExpandableNotificationRow mRow2; + private final NotificationData mNotificationData = new NotificationData(); + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager); // Bubbles get added to status bar window view mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager, @@ -74,7 +91,15 @@ public class BubbleControllerTest extends SysuiTestCase { mRow = mNotificationTestHelper.createBubble(); mRow2 = mNotificationTestHelper.createBubble(); + // Return non-null notification data from the NEM + when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData); + mBubbleController = new TestableBubbleController(mContext, mStatusBarWindowController); + + // Get a reference to the BubbleController's entry listener + verify(mNotificationEntryManager, atLeastOnce()) + .addNotificationEntryListener(mEntryListenerCaptor.capture()); + mEntryListener = mEntryListenerCaptor.getValue(); } @Test @@ -102,6 +127,8 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleController.removeBubble(mRow.getEntry().key); assertFalse(mStatusBarWindowController.getBubblesShowing()); + assertTrue(mRow.getEntry().isBubbleDismissed()); + verify(mNotificationEntryManager).updateNotifications(); } @Test @@ -112,6 +139,7 @@ public class BubbleControllerTest extends SysuiTestCase { mBubbleController.dismissStack(); assertFalse(mStatusBarWindowController.getBubblesShowing()); + verify(mNotificationEntryManager, times(3)).updateNotifications(); } @Test @@ -140,6 +168,12 @@ public class BubbleControllerTest extends SysuiTestCase { assertFalse(mBubbleController.isStackExpanded()); } + @Test + public void testMarkNewNotificationAsBubble() { + mEntryListener.onPendingEntryAdded(mRow.getEntry()); + assertTrue(mRow.getEntry().isBubble()); + } + static class TestableBubbleController extends BubbleController { TestableBubbleController(Context context, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index 8cf4b05b6371..e84e0f30c745 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -77,7 +77,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { @Mock private ShadeController mShadeController; private NotificationViewHierarchyManager mViewHierarchyManager; - private NotificationTestHelper mHelper = new NotificationTestHelper(mContext); + private NotificationTestHelper mHelper; @Before public void setUp() { @@ -90,6 +90,8 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager); mDependency.injectTestDependency(ShadeController.class, mShadeController); + mHelper = new NotificationTestHelper(mContext); + when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); mViewHierarchyManager = new NotificationViewHierarchyManager(mContext, @@ -262,9 +264,6 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { public void setMaxDisplayedNotifications(int maxNotifications) {} @Override - public void snapViewIfNeeded(Entry entry) {} - - @Override public ViewGroup getViewParentForNotification(NotificationData.Entry entry) { return null; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java index 871ff8998c20..6f4de1cc6dd8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java @@ -400,8 +400,7 @@ public class NotificationDataTest extends SysuiTestCase { Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon), title, PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)) - .setSemanticAction( - Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) + .setContextual(true) .build(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java index a2d408e4e97e..6197341acda5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java @@ -121,6 +121,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { @Mock private MetricsLogger mMetricsLogger; @Mock private SmartReplyController mSmartReplyController; @Mock private RowInflaterTask mAsyncInflationTask; + @Mock private NotificationRowBinder mMockedRowBinder; private NotificationData.Entry mEntry; private StatusBarNotification mSbn; @@ -256,7 +257,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // Check that no inflation error occurred. verify(mEntryListener, never()).onInflationError(any(), any()); - verify(mForegroundServiceController).addNotification(eq(mSbn), anyInt()); // Row inflation: ArgumentCaptor<NotificationData.Entry> entryCaptor = ArgumentCaptor.forClass( @@ -292,7 +292,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase { verify(mEntryListener, never()).onInflationError(any(), any()); verify(mPresenter).updateNotificationViews(); - verify(mForegroundServiceController).updateNotification(eq(mSbn), anyInt()); verify(mEntryListener).onEntryUpdated(mEntry); assertNotNull(mEntry.getRow()); assertEquals(mEntry.userSentiment, @@ -310,11 +309,10 @@ public class NotificationEntryManagerTest extends SysuiTestCase { verify(mEntryListener, never()).onInflationError(any(), any()); - verify(mForegroundServiceController).removeNotification(mSbn); verify(mListContainer).cleanUpViewStateForEntry(mEntry); verify(mPresenter).updateNotificationViews(); - verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), mSbn, - null, false /* lifetimeExtended */, false /* removedByUser */); + verify(mEntryListener).onEntryRemoved( + mEntry, null, false /* removedByUser */); verify(mRow).setRemoved(); assertNull(mEntryManager.getNotificationData().get(mSbn.getKey())); @@ -338,8 +336,31 @@ public class NotificationEntryManagerTest extends SysuiTestCase { assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey())); verify(extender).setShouldManageLifetime(mEntry, true /* shouldManage */); - verify(mEntryListener).onEntryRemoved(mEntry, mSbn.getKey(), null, - null, true /* lifetimeExtended */, false /* removedByUser */); + verify(mEntryListener, never()).onEntryRemoved( + mEntry, null, false /* removedByUser */); + } + + @Test + public void testRemoveNotification_onEntryRemoveNotFiredIfEntryDoesntExist() { + com.android.systemui.util.Assert.isNotMainThread(); + + mEntryManager.removeNotification("not_a_real_key", mRankingMap); + + verify(mEntryListener, never()).onEntryRemoved( + mEntry, null, false /* removedByUser */); + } + + @Test + public void testRemoveNotification_whilePending() throws InterruptedException { + com.android.systemui.util.Assert.isNotMainThread(); + + mEntryManager.setRowBinder(mMockedRowBinder); + + mEntryManager.addNotification(mSbn, mRankingMap); + mEntryManager.removeNotification(mSbn.getKey(), mRankingMap); + + verify(mEntryListener, never()).onEntryRemoved( + mEntry, null, false /* removedByUser */); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java index 983ca837b639..afdeb62a8f28 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java @@ -159,11 +159,6 @@ public class NotificationLoggerTest extends SysuiTestCase { verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any()); } - @Test - public void testHandleNullEntryOnEntryRemoved() { - mNotificationEntryListener.onEntryRemoved(null, "foobar", null, null, false, false); - } - private class TestableNotificationLogger extends NotificationLogger { TestableNotificationLogger(NotificationListener notificationListener, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 06be5f651ded..b66d0ab78fd8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -35,12 +35,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.os.Handler; -import android.os.IPowerManager; -import android.os.Looper; -import android.os.PowerManager; import android.provider.Settings; -import android.service.dreams.IDreamManager; import android.support.test.annotation.UiThreadTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -104,8 +99,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private NotificationData mNotificationData; @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; - @Mock private IDreamManager mDreamManager; - private PowerManager mPowerManager; private TestableNotificationEntryManager mEntryManager; private int mOriginalInterruptionModelSetting; @@ -122,12 +115,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mDependency.injectMockDependency(ShadeController.class); when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); - IPowerManager powerManagerService = mock(IPowerManager.class); - mPowerManager = new PowerManager(mContext, powerManagerService, - Handler.createAsync(Looper.myLooper())); - - mEntryManager = new TestableNotificationEntryManager(mPowerManager, - mContext); + mEntryManager = new TestableNotificationEntryManager(mContext); mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); Dependency.get(InitController.class).executePostInitTasks(); mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java index 56af40054316..79695fd6d38d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java @@ -237,8 +237,7 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase { mGroupManager.onEntryAdded(summaryEntry); mGroupManager.onEntryAdded(childEntry); - mNotificationEntryListener.onEntryRemoved(childEntry, childEntry.key, null, null, - false, false); + mNotificationEntryListener.onEntryRemoved(childEntry, null, false); assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index d57d56574e37..a45a5c4c3a0e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -205,7 +205,7 @@ public class StatusBarTest extends SysuiTestCase { mMetricsLogger = new FakeMetricsLogger(); mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); - mEntryManager = new TestableNotificationEntryManager(mPowerManager, mContext); + mEntryManager = new TestableNotificationEntryManager(mContext); mNotificationLogger = new NotificationLogger(mNotificationListener, Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController); mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger); @@ -761,9 +761,8 @@ public class StatusBarTest extends SysuiTestCase { public static class TestableNotificationEntryManager extends NotificationEntryManager { - public TestableNotificationEntryManager(PowerManager powerManager, Context context) { + public TestableNotificationEntryManager(Context context) { super(context); - mPowerManager = powerManager; } public void setUpForTest(NotificationPresenter presenter, diff --git a/packages/overlays/AccentColorBlackOverlay/res/values/strings.xml b/packages/overlays/AccentColorBlackOverlay/res/values/strings.xml index baf09b11ac07..da1036159d34 100644 --- a/packages/overlays/AccentColorBlackOverlay/res/values/strings.xml +++ b/packages/overlays/AccentColorBlackOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Black accent color name application label. [CHAR LIMIT=50] --> - <string name="accent_color_black_overlay" translatable="false">Black Accent Color</string> + <string name="accent_color_black_overlay" translatable="false">Black</string> </resources> diff --git a/packages/overlays/AccentColorGreenOverlay/res/values/strings.xml b/packages/overlays/AccentColorGreenOverlay/res/values/strings.xml index 4de344cbb65e..623a1dafb48d 100644 --- a/packages/overlays/AccentColorGreenOverlay/res/values/strings.xml +++ b/packages/overlays/AccentColorGreenOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Green accent color name application label. [CHAR LIMIT=50] --> - <string name="accent_color_green_overlay" translatable="false">Green Accent Color</string> + <string name="accent_color_green_overlay" translatable="false">Green</string> </resources> diff --git a/packages/overlays/AccentColorPurpleOverlay/res/values/strings.xml b/packages/overlays/AccentColorPurpleOverlay/res/values/strings.xml index d1eb95a940ac..d1c71688979e 100644 --- a/packages/overlays/AccentColorPurpleOverlay/res/values/strings.xml +++ b/packages/overlays/AccentColorPurpleOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Purple accent color name application label. [CHAR LIMIT=50] --> - <string name="accent_color_purple_overlay" translatable="false">Purple Accent Color</string> + <string name="accent_color_purple_overlay" translatable="false">Purple</string> </resources> diff --git a/packages/overlays/IconShapeRoundedRectOverlay/res/values/strings.xml b/packages/overlays/IconShapeRoundedRectOverlay/res/values/strings.xml index dc5c196c97aa..3c4c24db53ba 100644 --- a/packages/overlays/IconShapeRoundedRectOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeRoundedRectOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Rounded corner rectangle overlay --> - <string name="icon_shape_roundedrect_overlay" translatable="false">RoundedRectangle Icons</string> + <string name="icon_shape_roundedrect_overlay" translatable="false">Rounded Rectangle</string> </resources> diff --git a/packages/overlays/IconShapeSquareOverlay/res/values/strings.xml b/packages/overlays/IconShapeSquareOverlay/res/values/strings.xml index 4fd39ff26bae..577216582608 100644 --- a/packages/overlays/IconShapeSquareOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeSquareOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Square icon overlay --> - <string name="icon_shape_square_overlay" translatable="false">Square Icons</string> + <string name="icon_shape_square_overlay" translatable="false">Square</string> </resources> diff --git a/packages/overlays/IconShapeSquircleOverlay/res/values/strings.xml b/packages/overlays/IconShapeSquircleOverlay/res/values/strings.xml index b7c001c68a30..028eccb8c5a3 100644 --- a/packages/overlays/IconShapeSquircleOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeSquircleOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Squircle icon shape overlay --> - <string name="icon_shape_squircle_overlay" translatable="false">Square Icons</string> + <string name="icon_shape_squircle_overlay" translatable="false">Squircle</string> </resources> diff --git a/packages/overlays/IconShapeTeardropOverlay/res/values/strings.xml b/packages/overlays/IconShapeTeardropOverlay/res/values/strings.xml index d946ee8f97f2..db9fa9819714 100644 --- a/packages/overlays/IconShapeTeardropOverlay/res/values/strings.xml +++ b/packages/overlays/IconShapeTeardropOverlay/res/values/strings.xml @@ -18,6 +18,6 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Teardrop icon overlay --> - <string name="icon_shape_teardrop_overlay" translatable="false">Teardrop Icons</string> + <string name="icon_shape_teardrop_overlay" translatable="false">Teardrop</string> </resources> diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto index 3180b479b520..2b399defc21b 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -3684,7 +3684,7 @@ message MetricsEvent { ACTION_SETTINGS_TILE_CLICK = 830; // OPEN: Notification unsnoozed. CLOSE: Notification snoozed. UPDATE: snoozed notification - // updated + // updated. TYPE_DISMISS: snoozing canceled due to data being cleared on package // CATEGORY: NOTIFICATION // OS: O NOTIFICATION_SNOOZED = 831; @@ -6730,6 +6730,11 @@ message MetricsEvent { // OS: Q ZEN_CUSTOM_SETTINGS_DIALOG = 1612; + // OPEN: Settings > Developer Options > Game Update Packages + // CATEGORY: SETTINGS + // OS: Q + SETTINGS_GUP_DASHBOARD = 1613; + // ---- End Q Constants, all Q constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 8b07db7fc32d..6bd399042b29 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -127,7 +127,7 @@ public class BackupManagerService { protected void startServiceForUser(int userId) { UserBackupManagerService userBackupManagerService = UserBackupManagerService.createAndInitializeService( - userId, mContext, mTrampoline, mBackupThread, mTransportWhitelist); + userId, mContext, mTrampoline, mTransportWhitelist); startServiceForUser(userId, userBackupManagerService); } @@ -152,7 +152,11 @@ public class BackupManagerService { /** Stops the backup service for user {@code userId} when the user is stopped. */ @VisibleForTesting protected void stopServiceForUser(int userId) { - mServiceUsers.remove(userId); + UserBackupManagerService userBackupManagerService = mServiceUsers.removeReturnOld(userId); + + if (userBackupManagerService != null) { + userBackupManagerService.tearDownService(); + } } SparseArray<UserBackupManagerService> getServiceUsers() { diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java index 82638b4ecee4..5708b1c36822 100644 --- a/services/backup/java/com/android/server/backup/FullBackupJob.java +++ b/services/backup/java/com/android/server/backup/FullBackupJob.java @@ -24,15 +24,12 @@ import android.content.ComponentName; import android.content.Context; public class FullBackupJob extends JobService { - private static final String TAG = "FullBackupJob"; - private static final boolean DEBUG = true; - private static ComponentName sIdleService = new ComponentName("android", FullBackupJob.class.getName()); private static final int JOB_ID = 0x5038; - JobParameters mParams; + private JobParameters mParams; public static void schedule(Context ctx, long minDelay, BackupManagerConstants constants) { JobScheduler js = (JobScheduler) ctx.getSystemService(Context.JOB_SCHEDULER_SERVICE); diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java index bed520e9f068..3184bd87601a 100644 --- a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java +++ b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java @@ -13,8 +13,6 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Slog; -import com.android.server.backup.restore.PerformAdbRestoreTask; - import libcore.io.IoUtils; import java.io.File; @@ -42,11 +40,10 @@ public class KeyValueAdbRestoreEngine implements Runnable { private final UserBackupManagerService mBackupManagerService; private final File mDataDir; - FileMetadata mInfo; - PerformAdbRestoreTask mRestoreTask; - ParcelFileDescriptor mInFD; - IBackupAgent mAgent; - int mToken; + private final FileMetadata mInfo; + private final ParcelFileDescriptor mInFD; + private final IBackupAgent mAgent; + private final int mToken; public KeyValueAdbRestoreEngine(UserBackupManagerService backupManagerService, File dataDir, FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent, diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java index a0feaf9c8d15..aabd41a611a1 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java @@ -17,29 +17,35 @@ package com.android.server.backup; import android.os.Environment; +import android.os.UserHandle; import java.io.File; /** Directories used for user specific backup/restore persistent state and book-keeping. */ -public final class UserBackupManagerFiles { +final class UserBackupManagerFiles { // Name of the directories the service stores bookkeeping data under. private static final String BACKUP_PERSISTENT_DIR = "backup"; private static final String BACKUP_STAGING_DIR = "backup_stage"; + private static File getBaseDir(int userId) { + return Environment.getDataSystemCeDirectory(userId); + } + static File getBaseStateDir(int userId) { - // TODO (b/120424138) this should be per user + if (userId != UserHandle.USER_SYSTEM) { + return new File(getBaseDir(userId), BACKUP_PERSISTENT_DIR); + } + // TODO (b/120424138) remove if clause above and use same logic for system user. + // simultaneously, copy below dir to new system user dir return new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); } static File getDataDir(int userId) { - // TODO (b/120424138) this should be per user - // This dir on /cache is managed directly in init.rc + if (userId != UserHandle.USER_SYSTEM) { + return new File(getBaseDir(userId), BACKUP_STAGING_DIR); + } + // TODO (b/120424138) remove if clause above and use same logic for system user. Since this + // is a staging dir, we dont need to copy below dir to new system user dir return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR); } - - /** Directory used by full backup engine to store state. */ - public static File getFullBackupEngineFilesDir(int userId) { - // TODO (b/120424138) this should be per user - return new File("/data/system"); - } } diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 6425508829ce..bfaa22117d19 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -110,9 +110,9 @@ import com.android.server.backup.internal.ClearDataObserver; import com.android.server.backup.internal.OnTaskFinishedListener; import com.android.server.backup.internal.Operation; import com.android.server.backup.internal.PerformInitializeTask; -import com.android.server.backup.internal.ProvisionedObserver; import com.android.server.backup.internal.RunBackupReceiver; import com.android.server.backup.internal.RunInitializeReceiver; +import com.android.server.backup.internal.SetupObserver; import com.android.server.backup.keyvalue.BackupRequest; import com.android.server.backup.params.AdbBackupParams; import com.android.server.backup.params.AdbParams; @@ -208,8 +208,8 @@ public class UserBackupManagerService { public static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN"; public static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT"; - public static final String BACKUP_FINISHED_ACTION = "android.intent.action.BACKUP_FINISHED"; - public static final String BACKUP_FINISHED_PACKAGE_EXTRA = "packageName"; + private static final String BACKUP_FINISHED_ACTION = "android.intent.action.BACKUP_FINISHED"; + private static final String BACKUP_FINISHED_PACKAGE_EXTRA = "packageName"; // Bookkeeping of in-flight operations. The operation token is the index of the entry in the // pending operations list. @@ -245,26 +245,27 @@ public class UserBackupManagerService { private final @UserIdInt int mUserId; private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final TransportManager mTransportManager; + private final HandlerThread mUserBackupThread; - private Context mContext; - private PackageManager mPackageManager; - private IPackageManager mPackageManagerBinder; - private IActivityManager mActivityManager; + private final Context mContext; + private final PackageManager mPackageManager; + private final IPackageManager mPackageManagerBinder; + private final IActivityManager mActivityManager; private PowerManager mPowerManager; - private AlarmManager mAlarmManager; - private IStorageManager mStorageManager; - private BackupManagerConstants mConstants; - private PowerManager.WakeLock mWakelock; - private BackupHandler mBackupHandler; + private final AlarmManager mAlarmManager; + private final IStorageManager mStorageManager; + private final BackupManagerConstants mConstants; + private final PowerManager.WakeLock mWakelock; + private final BackupHandler mBackupHandler; - private IBackupManager mBackupManagerBinder; + private final IBackupManager mBackupManagerBinder; private boolean mEnabled; // access to this is synchronized on 'this' - private boolean mProvisioned; + private boolean mSetupComplete; private boolean mAutoRestore; - private PendingIntent mRunBackupIntent; - private PendingIntent mRunInitIntent; + private final PendingIntent mRunBackupIntent; + private final PendingIntent mRunInitIntent; private final ArraySet<String> mPendingInits = new ArraySet<>(); // transport names @@ -272,7 +273,7 @@ public class UserBackupManagerService { private final SparseArray<HashSet<String>> mBackupParticipants = new SparseArray<>(); // Backups that we haven't started yet. Keys are package names. - private HashMap<String, BackupRequest> mPendingBackups = new HashMap<>(); + private final HashMap<String, BackupRequest> mPendingBackups = new HashMap<>(); // locking around the pending-backup management private final Object mQueueLock = new Object(); @@ -314,9 +315,6 @@ public class UserBackupManagerService { private ActiveRestoreSession mActiveRestoreSession; - // Watch the device provisioning operation during setup - private ContentObserver mProvisionedObserver; - /** * mCurrentOperations contains the list of currently active operations. * @@ -342,7 +340,7 @@ public class UserBackupManagerService { private final SparseArray<Operation> mCurrentOperations = new SparseArray<>(); private final Object mCurrentOpLock = new Object(); private final Random mTokenGenerator = new Random(); - final AtomicInteger mNextToken = new AtomicInteger(); + private final AtomicInteger mNextToken = new AtomicInteger(); // Where we keep our journal files and other bookkeeping. private final File mBaseStateDir; @@ -350,7 +348,7 @@ public class UserBackupManagerService { private final File mJournalDir; @Nullable private DataChangedJournal mJournal; - private File mFullBackupScheduleFile; + private final File mFullBackupScheduleFile; // Keep a log of all the apps we've ever backed up. private ProcessedPackagesJournal mProcessedPackagesJournal; @@ -371,11 +369,10 @@ public class UserBackupManagerService { @UserIdInt int userId, Context context, Trampoline trampoline, - HandlerThread backupThread, Set<ComponentName> transportWhitelist) { String currentTransport = - Settings.Secure.getString( - context.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT); + Settings.Secure.getStringForUser( + context.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT, userId); if (TextUtils.isEmpty(currentTransport)) { currentTransport = null; } @@ -389,8 +386,21 @@ public class UserBackupManagerService { File baseStateDir = UserBackupManagerFiles.getBaseStateDir(userId); File dataDir = UserBackupManagerFiles.getDataDir(userId); + HandlerThread userBackupThread = + new HandlerThread("backup-" + userId, Process.THREAD_PRIORITY_BACKGROUND); + userBackupThread.start(); + if (DEBUG) { + Slog.d(TAG, "Started thread " + userBackupThread.getName() + " for user " + userId); + } + return createAndInitializeService( - userId, context, trampoline, backupThread, baseStateDir, dataDir, transportManager); + userId, + context, + trampoline, + userBackupThread, + baseStateDir, + dataDir, + transportManager); } /** @@ -399,7 +409,7 @@ public class UserBackupManagerService { * @param userId The user which this service is for. * @param context The system server context. * @param trampoline A reference to the proxy to {@link BackupManagerService}. - * @param backupThread The thread running backup/restore operations for the user. + * @param userBackupThread The thread running backup/restore operations for the user. * @param baseStateDir The directory we store the user's persistent bookkeeping data. * @param dataDir The directory we store the user's temporary staging data. * @param transportManager The {@link TransportManager} responsible for handling the user's @@ -410,19 +420,38 @@ public class UserBackupManagerService { @UserIdInt int userId, Context context, Trampoline trampoline, - HandlerThread backupThread, + HandlerThread userBackupThread, File baseStateDir, File dataDir, TransportManager transportManager) { return new UserBackupManagerService( - userId, context, trampoline, backupThread, baseStateDir, dataDir, transportManager); + userId, + context, + trampoline, + userBackupThread, + baseStateDir, + dataDir, + transportManager); + } + + /** + * Returns the value of {@link Settings.Secure#USER_SETUP_COMPLETE} for the specified user + * {@code userId} as a {@code boolean}. + */ + public static boolean getSetupCompleteSettingForUser(Context context, int userId) { + return Settings.Secure.getIntForUser( + context.getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, + 0, + userId) + != 0; } private UserBackupManagerService( @UserIdInt int userId, Context context, Trampoline parent, - HandlerThread backupThread, + HandlerThread userBackupThread, File baseStateDir, File dataDir, TransportManager transportManager) { @@ -443,21 +472,22 @@ public class UserBackupManagerService { BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver()); mAgentTimeoutParameters.start(); - // spin up the backup/restore handler thread - checkNotNull(backupThread, "backupThread cannot be null"); - mBackupHandler = new BackupHandler(this, backupThread.getLooper()); + checkNotNull(userBackupThread, "userBackupThread cannot be null"); + mUserBackupThread = userBackupThread; + mBackupHandler = new BackupHandler(this, userBackupThread.getLooper()); // Set up our bookkeeping final ContentResolver resolver = context.getContentResolver(); - mProvisioned = Settings.Global.getInt(resolver, - Settings.Global.DEVICE_PROVISIONED, 0) != 0; - mAutoRestore = Settings.Secure.getInt(resolver, - Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0; + mSetupComplete = getSetupCompleteSettingForUser(context, userId); + mAutoRestore = Settings.Secure.getIntForUser(resolver, + Settings.Secure.BACKUP_AUTO_RESTORE, 1, userId) != 0; - mProvisionedObserver = new ProvisionedObserver(this, mBackupHandler); + ContentObserver setupObserver = new SetupObserver(this, mBackupHandler); resolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), - false, mProvisionedObserver); + Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), + /* notifyForDescendents */ false, + setupObserver, + mUserId); mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null"); mBaseStateDir.mkdirs(); @@ -526,6 +556,15 @@ public class UserBackupManagerService { mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"); } + /** Cleans up state when the user of this service is stopped. */ + void tearDownService() { + mUserBackupThread.quit(); + } + + public @UserIdInt int getUserId() { + return mUserId; + } + public BackupManagerConstants getConstants() { return mConstants; } @@ -538,51 +577,27 @@ public class UserBackupManagerService { return mContext; } - public void setContext(Context context) { - mContext = context; - } - public PackageManager getPackageManager() { return mPackageManager; } - public void setPackageManager(PackageManager packageManager) { - mPackageManager = packageManager; - } - public IPackageManager getPackageManagerBinder() { return mPackageManagerBinder; } - public void setPackageManagerBinder(IPackageManager packageManagerBinder) { - mPackageManagerBinder = packageManagerBinder; - } - public IActivityManager getActivityManager() { return mActivityManager; } - public void setActivityManager(IActivityManager activityManager) { - mActivityManager = activityManager; - } - public AlarmManager getAlarmManager() { return mAlarmManager; } - public void setAlarmManager(AlarmManager alarmManager) { - mAlarmManager = alarmManager; - } - @VisibleForTesting void setPowerManager(PowerManager powerManager) { mPowerManager = powerManager; } - public void setBackupManagerBinder(IBackupManager backupManagerBinder) { - mBackupManagerBinder = backupManagerBinder; - } - public TransportManager getTransportManager() { return mTransportManager; } @@ -595,12 +610,12 @@ public class UserBackupManagerService { mEnabled = enabled; } - public boolean isProvisioned() { - return mProvisioned; + public boolean isSetupComplete() { + return mSetupComplete; } - public void setProvisioned(boolean provisioned) { - mProvisioned = provisioned; + public void setSetupComplete(boolean setupComplete) { + mSetupComplete = setupComplete; } public PowerManager.WakeLock getWakelock() { @@ -617,35 +632,18 @@ public class UserBackupManagerService { mWakelock.setWorkSource(workSource); } - public void setWakelock(PowerManager.WakeLock wakelock) { - mWakelock = wakelock; - } - public Handler getBackupHandler() { return mBackupHandler; } - public void setBackupHandler(BackupHandler backupHandler) { - mBackupHandler = backupHandler; - } - public PendingIntent getRunInitIntent() { return mRunInitIntent; } - public void setRunInitIntent(PendingIntent runInitIntent) { - mRunInitIntent = runInitIntent; - } - public HashMap<String, BackupRequest> getPendingBackups() { return mPendingBackups; } - public void setPendingBackups( - HashMap<String, BackupRequest> pendingBackups) { - mPendingBackups = pendingBackups; - } - public Object getQueueLock() { return mQueueLock; } @@ -658,10 +656,6 @@ public class UserBackupManagerService { mBackupRunning = backupRunning; } - public long getLastBackupPass() { - return mLastBackupPass; - } - public void setLastBackupPass(long lastBackupPass) { mLastBackupPass = lastBackupPass; } @@ -670,10 +664,6 @@ public class UserBackupManagerService { return mClearDataLock; } - public boolean isClearingData() { - return mClearingData; - } - public void setClearingData(boolean clearingData) { mClearingData = clearingData; } @@ -694,11 +684,6 @@ public class UserBackupManagerService { return mActiveRestoreSession; } - public void setActiveRestoreSession( - ActiveRestoreSession activeRestoreSession) { - mActiveRestoreSession = activeRestoreSession; - } - public SparseArray<Operation> getCurrentOperations() { return mCurrentOperations; } @@ -732,18 +717,10 @@ public class UserBackupManagerService { return mRng; } - public Set<String> getAncestralPackages() { - return mAncestralPackages; - } - public void setAncestralPackages(Set<String> ancestralPackages) { mAncestralPackages = ancestralPackages; } - public long getAncestralToken() { - return mAncestralToken; - } - public void setAncestralToken(long ancestralToken) { mAncestralToken = ancestralToken; } @@ -1553,11 +1530,16 @@ public class UserBackupManagerService { throw new IllegalArgumentException("No packages are provided for backup"); } - if (!mEnabled || !mProvisioned) { - Slog.i(TAG, "Backup requested but e=" + mEnabled + " p=" + mProvisioned); + if (!mEnabled || !mSetupComplete) { + Slog.i( + TAG, + "Backup requested but enabled=" + + mEnabled + + " setupComplete=" + + mSetupComplete); BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_BACKUP_NOT_ALLOWED); - final int logTag = mProvisioned + final int logTag = mSetupComplete ? BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED : BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED; monitor = BackupManagerMonitorUtils.monitorEvent(monitor, logTag, null, @@ -1992,13 +1974,13 @@ public class UserBackupManagerService { FullBackupEntry entry = null; long latency = fullBackupInterval; - if (!mEnabled || !mProvisioned) { + if (!mEnabled || !mSetupComplete) { // Backups are globally disabled, so don't proceed. We also don't reschedule // the job driving automatic backups; that job will be scheduled again when // the user enables backup. if (MORE_DEBUG) { - Slog.i(TAG, "beginFullBackup but e=" + mEnabled - + " p=" + mProvisioned + "; ignoring"); + Slog.i(TAG, "beginFullBackup but enabled=" + mEnabled + + " setupComplete=" + mSetupComplete + "; ignoring"); } return false; } @@ -2399,12 +2381,6 @@ public class UserBackupManagerService { } } - /** Returns {@code true} if the system user has gone through SUW. */ - public boolean deviceIsProvisioned() { - final ContentResolver resolver = mContext.getContentResolver(); - return (Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0); - } - /** * Used by 'adb backup' to run a backup pass for packages supplied via the command line, writing * the resulting data stream to the supplied {@code fd}. This method is synchronous and does not @@ -2437,8 +2413,7 @@ public class UserBackupManagerService { long oldId = Binder.clearCallingIdentity(); try { - // Doesn't make sense to do a full backup prior to setup - if (!deviceIsProvisioned()) { + if (!mSetupComplete) { Slog.i(TAG, "Backup not supported before setup"); return; } @@ -2564,9 +2539,7 @@ public class UserBackupManagerService { long oldId = Binder.clearCallingIdentity(); try { - // Check whether the device has been provisioned -- we don't handle - // full restores prior to completing the setup process. - if (!deviceIsProvisioned()) { + if (!mSetupComplete) { Slog.i(TAG, "Full restore not permitted before setup"); return; } @@ -2721,7 +2694,7 @@ public class UserBackupManagerService { } synchronized (mQueueLock) { - if (enable && !wasEnabled && mProvisioned) { + if (enable && !wasEnabled && mSetupComplete) { // if we've just been enabled, start scheduling backup passes KeyValueBackupJob.schedule(mContext, mConstants); scheduleNextFullBackupJob(0); @@ -2734,7 +2707,7 @@ public class UserBackupManagerService { // This also constitutes an opt-out, so we wipe any data for // this device from the backend. We start that process with // an alarm in order to guarantee wakelock states. - if (wasEnabled && mProvisioned) { + if (wasEnabled && mSetupComplete) { // NOTE: we currently flush every registered transport, not just // the currently-active one. List<String> transportNames = new ArrayList<>(); @@ -2782,8 +2755,8 @@ public class UserBackupManagerService { final long oldId = Binder.clearCallingIdentity(); try { synchronized (this) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.BACKUP_AUTO_RESTORE, doAutoRestore ? 1 : 0); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.BACKUP_AUTO_RESTORE, doAutoRestore ? 1 : 0, mUserId); mAutoRestore = doAutoRestore; } } finally { @@ -2996,8 +2969,8 @@ public class UserBackupManagerService { private void updateStateForTransport(String newTransportName) { // Publish the name change - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.BACKUP_TRANSPORT, newTransportName); + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.BACKUP_TRANSPORT, newTransportName, mUserId); // And update our current-dataset bookkeeping String callerLogString = "BMS.updateStateForTransport()"; @@ -3112,8 +3085,7 @@ public class UserBackupManagerService { synchronized (mAgentConnectLock) { if (Binder.getCallingUid() == Process.SYSTEM_UID) { Slog.d(TAG, "agentConnected pkg=" + packageName + " agent=" + agentBinder); - IBackupAgent agent = IBackupAgent.Stub.asInterface(agentBinder); - mConnectedAgent = agent; + mConnectedAgent = IBackupAgent.Stub.asInterface(agentBinder); mConnecting = false; } else { Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid() @@ -3431,7 +3403,7 @@ public class UserBackupManagerService { private void dumpInternal(PrintWriter pw) { synchronized (mQueueLock) { pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled") - + " / " + (!mProvisioned ? "not " : "") + "provisioned / " + + " / " + (!mSetupComplete ? "not " : "") + "setup complete / " + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init"); pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled")); if (mBackupRunning) pw.println("Backup currently running"); diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java index 45ca2af54b52..03d4e97cb998 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java +++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java @@ -34,14 +34,12 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.os.UserHandle; import android.util.Slog; import com.android.internal.util.Preconditions; import com.android.server.AppWidgetBackupBridge; import com.android.server.backup.BackupAgentTimeoutParameters; import com.android.server.backup.BackupRestoreTask; -import com.android.server.backup.UserBackupManagerFiles; import com.android.server.backup.UserBackupManagerService; import com.android.server.backup.remote.RemoteCall; import com.android.server.backup.utils.FullBackupUtils; @@ -78,21 +76,21 @@ public class FullBackupEngine { private final File mFilesDir; FullBackupRunner( + UserBackupManagerService userBackupManagerService, PackageInfo packageInfo, IBackupAgent agent, ParcelFileDescriptor pipe, int token, boolean includeApks) throws IOException { - // TODO: http://b/22388012 - mUserId = UserHandle.USER_SYSTEM; + mUserId = userBackupManagerService.getUserId(); mPackageManager = backupManagerService.getPackageManager(); mPackage = packageInfo; mAgent = agent; mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor()); mToken = token; mIncludeApks = includeApks; - mFilesDir = UserBackupManagerFiles.getFullBackupEngineFilesDir(mUserId); + mFilesDir = userBackupManagerService.getDataDir(); } @Override @@ -155,9 +153,12 @@ public class FullBackupEngine { backupManagerService.getBackupManagerBinder(), mTransportFlags); } catch (IOException e) { - Slog.e(TAG, "Error running full backup for " + mPackage.packageName); + Slog.e(TAG, "Error running full backup for " + mPackage.packageName, e); } catch (RemoteException e) { - Slog.e(TAG, "Remote agent vanished during full backup of " + mPackage.packageName); + Slog.e( + TAG, + "Remote agent vanished during full backup of " + mPackage.packageName, + e); } finally { try { mPipe.close(); @@ -233,7 +234,13 @@ public class FullBackupEngine { pipes = ParcelFileDescriptor.createPipe(); FullBackupRunner runner = - new FullBackupRunner(mPkg, mAgent, pipes[1], mOpToken, mIncludeApks); + new FullBackupRunner( + backupManagerService, + mPkg, + mAgent, + pipes[1], + mOpToken, + mIncludeApks); pipes[1].close(); // the runner has dup'd it pipes[1] = null; Thread t = new Thread(runner, "app-data-runner"); diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java index 5b449c5b400e..2ee96d190f90 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java +++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java @@ -317,16 +317,16 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba int backupRunStatus = BackupManager.SUCCESS; try { - if (!backupManagerService.isEnabled() || !backupManagerService.isProvisioned()) { + if (!backupManagerService.isEnabled() || !backupManagerService.isSetupComplete()) { // Backups are globally disabled, so don't proceed. if (DEBUG) { Slog.i(TAG, "full backup requested but enabled=" + backupManagerService .isEnabled() - + " provisioned=" + backupManagerService.isProvisioned() + + " setupComplete=" + backupManagerService.isSetupComplete() + "; ignoring"); } int monitoringEvent; - if (backupManagerService.isProvisioned()) { + if (backupManagerService.isSetupComplete()) { monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED; } else { monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED; diff --git a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java deleted file mode 100644 index 7e2ac796d343..000000000000 --- a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017 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.backup.internal; - -import static com.android.server.backup.BackupManagerService.MORE_DEBUG; -import static com.android.server.backup.BackupManagerService.TAG; - -import android.database.ContentObserver; -import android.os.Handler; -import android.util.Slog; - -import com.android.server.backup.KeyValueBackupJob; -import com.android.server.backup.UserBackupManagerService; - -public class ProvisionedObserver extends ContentObserver { - - private UserBackupManagerService backupManagerService; - - public ProvisionedObserver( - UserBackupManagerService backupManagerService, Handler handler) { - super(handler); - this.backupManagerService = backupManagerService; - } - - public void onChange(boolean selfChange) { - final boolean wasProvisioned = backupManagerService.isProvisioned(); - final boolean isProvisioned = backupManagerService.deviceIsProvisioned(); - // latch: never unprovision - backupManagerService.setProvisioned(wasProvisioned || isProvisioned); - if (MORE_DEBUG) { - Slog.d(TAG, "Provisioning change: was=" + wasProvisioned - + " is=" + isProvisioned + " now=" + backupManagerService.isProvisioned()); - } - - synchronized (backupManagerService.getQueueLock()) { - if (backupManagerService.isProvisioned() && !wasProvisioned - && backupManagerService.isEnabled()) { - // we're now good to go, so start the backup alarms - if (MORE_DEBUG) { - Slog.d(TAG, "Now provisioned, so starting backups"); - } - KeyValueBackupJob.schedule(backupManagerService.getContext(), - backupManagerService.getConstants()); - backupManagerService.scheduleNextFullBackupJob(0); - } - } - } -} diff --git a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java index 2a5d913226b9..3b877241f7f4 100644 --- a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java +++ b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java @@ -59,7 +59,8 @@ public class RunBackupReceiver extends BroadcastReceiver { } else { // Don't run backups now if we're disabled or not yet // fully set up. - if (backupManagerService.isEnabled() && backupManagerService.isProvisioned()) { + if (backupManagerService.isEnabled() + && backupManagerService.isSetupComplete()) { if (!backupManagerService.isBackupRunning()) { if (DEBUG) { Slog.v(TAG, "Running a backup pass"); @@ -77,8 +78,8 @@ public class RunBackupReceiver extends BroadcastReceiver { Slog.i(TAG, "Backup time but one already running"); } } else { - Slog.w(TAG, "Backup pass but e=" + backupManagerService.isEnabled() + " p=" - + backupManagerService.isProvisioned()); + Slog.w(TAG, "Backup pass but enabled=" + backupManagerService.isEnabled() + + " setupComplete=" + backupManagerService.isSetupComplete()); } } } diff --git a/services/backup/java/com/android/server/backup/internal/SetupObserver.java b/services/backup/java/com/android/server/backup/internal/SetupObserver.java new file mode 100644 index 000000000000..defcacc50a18 --- /dev/null +++ b/services/backup/java/com/android/server/backup/internal/SetupObserver.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 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.backup.internal; + +import static com.android.server.backup.BackupManagerService.MORE_DEBUG; +import static com.android.server.backup.BackupManagerService.TAG; +import static com.android.server.backup.UserBackupManagerService.getSetupCompleteSettingForUser; + +import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.provider.Settings; +import android.util.Slog; + +import com.android.server.backup.KeyValueBackupJob; +import com.android.server.backup.UserBackupManagerService; + +/** + * A {@link ContentObserver} for changes to the setting {@link Settings.Secure#USER_SETUP_COMPLETE} + * for a particular user. + */ +public class SetupObserver extends ContentObserver { + private final UserBackupManagerService mUserBackupManagerService; + private final Context mContext; + private final int mUserId; + + public SetupObserver(UserBackupManagerService userBackupManagerService, Handler handler) { + super(handler); + mUserBackupManagerService = userBackupManagerService; + mContext = userBackupManagerService.getContext(); + mUserId = userBackupManagerService.getUserId(); + } + + /** + * Callback that executes when the setting {@link Settings.Secure#USER_SETUP_COMPLETE} changes + * for the user {@link #mUserId}. If the user is newly setup and backup is enabled, then we + * schedule a key value and full backup job for the user. If the user was previously setup and + * now the setting has changed to {@code false}, we don't reset the state as having gone through + * setup is a non-reversible action. + */ + public void onChange(boolean selfChange) { + boolean previousSetupComplete = mUserBackupManagerService.isSetupComplete(); + boolean newSetupComplete = getSetupCompleteSettingForUser(mContext, mUserId); + + boolean resolvedSetupComplete = previousSetupComplete || newSetupComplete; + mUserBackupManagerService.setSetupComplete(resolvedSetupComplete); + if (MORE_DEBUG) { + Slog.d( + TAG, + "Setup complete change: was=" + + previousSetupComplete + + " new=" + + newSetupComplete + + " resolved=" + + resolvedSetupComplete); + } + + synchronized (mUserBackupManagerService.getQueueLock()) { + // Start backup if the user is newly setup and backup is enabled. + if (resolvedSetupComplete + && !previousSetupComplete + && mUserBackupManagerService.isEnabled()) { + if (MORE_DEBUG) { + Slog.d(TAG, "Setup complete so starting backups"); + } + KeyValueBackupJob.schedule(mContext, mUserBackupManagerService.getConstants()); + mUserBackupManagerService.scheduleNextFullBackupJob(0); + } + } + } +} diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java index 0d26ea56faa2..45a398f80351 100644 --- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java +++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java @@ -678,12 +678,13 @@ public class FullRestoreEngine extends RestoreEngine { * Returns whether the package is in the list of the packages for which clear app data should * be called despite the fact that they have backup agent. * - * <p>The list is read from {@link Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE}. + * <p>The list is read from {@link Settings.Secure#PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE}. */ private boolean shouldForceClearAppDataOnFullRestore(String packageName) { - String packageListString = Settings.Secure.getString( + String packageListString = Settings.Secure.getStringForUser( mBackupManagerService.getContext().getContentResolver(), - Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE); + Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE, + mBackupManagerService.getUserId()); if (TextUtils.isEmpty(packageListString)) { return false; } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index d07cf78e47ed..e10e0d6ef1ce 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -1313,16 +1313,17 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyDataConnection(int state, boolean isDataAllowed, - String reason, String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { + public void notifyDataConnection(int state, boolean isDataAllowed, String apn, String apnType, + LinkProperties linkProperties, + NetworkCapabilities networkCapabilities, int networkType, + boolean roaming) { notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, - isDataAllowed,reason, apn, apnType, linkProperties, - networkCapabilities, networkType, roaming); + isDataAllowed, apn, apnType, linkProperties, + networkCapabilities, networkType, roaming); } - public void notifyDataConnectionForSubscriber(int subId, int state, - boolean isDataAllowed, String reason, String apn, String apnType, + public void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataAllowed, + String apn, String apnType, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { if (!checkNotifyPermission("notifyDataConnection()" )) { @@ -1331,7 +1332,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (VDBG) { log("notifyDataConnectionForSubscriber: subId=" + subId + " state=" + state + " isDataAllowed=" + isDataAllowed - + " reason='" + reason + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType + " mRecords.size()=" + mRecords.size()); } @@ -1366,7 +1366,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType[phoneId] = networkType; } mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, - apnType, apn, reason, linkProperties, ""); + apnType, apn, linkProperties, ""); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1381,30 +1381,29 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } handleRemoveListLocked(); } - broadcastDataConnectionStateChanged(state, isDataAllowed, reason, apn, - apnType, linkProperties, networkCapabilities, roaming, subId); - broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, + broadcastDataConnectionStateChanged(state, isDataAllowed, apn, apnType, linkProperties, + networkCapabilities, roaming, subId); + broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, linkProperties, ""); } - public void notifyDataConnectionFailed(String reason, String apnType) { + public void notifyDataConnectionFailed(String apnType) { notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, - reason, apnType); + apnType); } - public void notifyDataConnectionFailedForSubscriber(int subId, - String reason, String apnType) { + public void notifyDataConnectionFailedForSubscriber(int subId, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; } if (VDBG) { log("notifyDataConnectionFailedForSubscriber: subId=" + subId - + " reason=" + reason + " apnType=" + apnType); + + " apnType=" + apnType); } synchronized (mRecords) { mPreciseDataConnectionState = new PreciseDataConnectionState( TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, "", reason, null, ""); + apnType, "", null, ""); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1417,9 +1416,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } handleRemoveListLocked(); } - broadcastDataConnectionFailed(reason, apnType, subId); + broadcastDataConnectionFailed(apnType, subId); broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); + TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", null, ""); } public void notifyCellLocation(Bundle cellLocation) { @@ -1529,15 +1528,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyPreciseDataConnectionFailed(String reason, String apnType, - String apn, String failCause) { + public void notifyPreciseDataConnectionFailed(String apnType, String apn, String failCause) { if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { return; } synchronized (mRecords) { mPreciseDataConnectionState = new PreciseDataConnectionState( TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, apn, reason, null, failCause); + apnType, apn, null, failCause); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { @@ -1551,7 +1549,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { handleRemoveListLocked(); } broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); + TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, null, failCause); } @Override @@ -1881,10 +1879,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_CALL_LOG}); } - private void broadcastDataConnectionStateChanged(int state, - boolean isDataAllowed, - String reason, String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, boolean roaming, int subId) { + private void broadcastDataConnectionStateChanged(int state, boolean isDataAllowed, String apn, + String apnType, LinkProperties linkProperties, + NetworkCapabilities networkCapabilities, + boolean roaming, int subId) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. @@ -1894,9 +1892,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (!isDataAllowed) { intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); } - if (reason != null) { - intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); - } if (linkProperties != null) { intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); String iface = linkProperties.getInterfaceName(); @@ -1915,17 +1910,15 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void broadcastDataConnectionFailed(String reason, String apnType, - int subId) { + private void broadcastDataConnectionFailed(String apnType, int subId) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); - intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, - int backgroundCallState) { + int backgroundCallState) { Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); @@ -1935,16 +1928,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, - String apnType, String apn, String reason, LinkProperties linkProperties, - String failCause) { + String apnType, String apn, + LinkProperties linkProperties, + String failCause) { Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); intent.putExtra(PhoneConstants.STATE_KEY, state); intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); - if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); if (linkProperties != null) { - intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties); + intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); } if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index a94fa12e4f35..ed39d8302bf7 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2503,6 +2503,9 @@ public final class ActiveServices { && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingType = "webview_service"; } + if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) { + hostingType = "app_zygote"; + } } // Not running -- get it started, and enqueue this service record diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b053979f1fcd..bc21610dd602 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -235,6 +235,7 @@ import android.media.audiofx.AudioEffect; import android.net.Proxy; import android.net.ProxyInfo; import android.net.Uri; +import android.os.AppZygote; import android.os.BatteryStats; import android.os.Binder; import android.os.BinderProxy; @@ -452,6 +453,9 @@ public class ActivityManagerService extends IActivityManager.Stub // before we decide it must be hung. static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; + // How long we wait to kill an application zygote, after the last process using + // it has gone away. + static final int KILL_APP_ZYGOTE_DELAY_MS = 5 * 1000; /** * How long we wait for an provider to be published. Should be longer than * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}. @@ -1441,6 +1445,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int PUSH_TEMP_WHITELIST_UI_MSG = 68; static final int SERVICE_FOREGROUND_CRASH_MSG = 69; static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70; + static final int KILL_APP_ZYGOTE_MSG = 71; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1644,6 +1649,12 @@ public class ActivityManagerService extends IActivityManager.Stub false, userId, reason); } } break; + case KILL_APP_ZYGOTE_MSG: { + synchronized (ActivityManagerService.this) { + final AppZygote appZygote = (AppZygote) msg.obj; + mProcessList.killAppZygoteIfNeededLocked(appZygote); + } + } break; case CHECK_EXCESSIVE_POWER_USE_MSG: { synchronized (ActivityManagerService.this) { checkExcessivePowerUsageLocked(); @@ -1932,7 +1943,8 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName, false, - 0); + 0, + false); app.setPersistent(true); app.pid = MY_PID; app.getWindowProcessController().setPid(MY_PID); @@ -7396,7 +7408,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (app == null) { - app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0); + app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0, false); mProcessList.updateLruProcessLocked(app, false, null); updateOomAdjLocked(); } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index d133deaf4b8e..9898d06837be 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -19,8 +19,6 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityThread.PROC_START_SEQ_IDENT; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO; -import static android.os.Process.FIRST_ISOLATED_UID; -import static android.os.Process.LAST_ISOLATED_UID; import static android.os.Process.SYSTEM_UID; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.getFreeMemory; @@ -34,6 +32,8 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS; +import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG; import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK; import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT; import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG; @@ -58,6 +58,7 @@ import android.graphics.Point; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.Uri; +import android.os.AppZygote; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -75,10 +76,12 @@ import android.os.UserHandle; import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.EventLog; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.StatsLog; import android.view.Display; @@ -108,6 +111,7 @@ import java.io.PrintWriter; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.List; /** @@ -354,10 +358,136 @@ public final class ProcessList { final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>(); /** - * Counter for assigning isolated process uids, to avoid frequently reusing the - * same ones. + * The currently running application zygotes. */ - int mNextIsolatedProcessUid = 0; + final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>(); + + /** + * The processes that are forked off an application zygote. + */ + final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses = + new ArrayMap<AppZygote, ArrayList<ProcessRecord>>(); + + final class IsolatedUidRange { + @VisibleForTesting + public final int mFirstUid; + @VisibleForTesting + public final int mLastUid; + + @GuardedBy("ProcessList.this.mService") + private final SparseBooleanArray mUidUsed = new SparseBooleanArray(); + + @GuardedBy("ProcessList.this.mService") + private int mNextUid; + + IsolatedUidRange(int firstUid, int lastUid) { + mFirstUid = firstUid; + mLastUid = lastUid; + mNextUid = firstUid; + } + + @GuardedBy("ProcessList.this.mService") + int allocateIsolatedUidLocked(int userId) { + int uid; + int stepsLeft = (mLastUid - mFirstUid + 1); + for (int i = 0; i < stepsLeft; ++i) { + if (mNextUid < mFirstUid || mNextUid > mLastUid) { + mNextUid = mFirstUid; + } + uid = UserHandle.getUid(userId, mNextUid); + mNextUid++; + if (!mUidUsed.get(uid, false)) { + mUidUsed.put(uid, true); + return uid; + } + } + return -1; + } + + @GuardedBy("ProcessList.this.mService") + void freeIsolatedUidLocked(int uid) { + // Strip out userId + final int appId = UserHandle.getAppId(uid); + mUidUsed.delete(appId); + } + }; + + /** + * A class that allocates ranges of isolated UIDs per application, and keeps track of them. + */ + final class IsolatedUidRangeAllocator { + private final int mFirstUid; + private final int mNumUidRanges; + private final int mNumUidsPerRange; + /** + * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange) + * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that. + */ + @GuardedBy("ProcessList.this.mService") + private final BitSet mAvailableUidRanges; + @GuardedBy("ProcessList.this.mService") + private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>(); + + IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) { + mFirstUid = firstUid; + mNumUidsPerRange = numUidsPerRange; + mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange; + mAvailableUidRanges = new BitSet(mNumUidRanges); + // Mark all as available + mAvailableUidRanges.set(0, mNumUidRanges); + } + + @GuardedBy("ProcessList.this.mService") + IsolatedUidRange getIsolatedUidRangeLocked(ApplicationInfo info) { + return mAppRanges.get(info.processName, info.uid); + } + + @GuardedBy("ProcessList.this.mService") + IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info) { + IsolatedUidRange range = getIsolatedUidRangeLocked(info); + if (range == null) { + int uidRangeIndex = mAvailableUidRanges.nextSetBit(0); + if (uidRangeIndex < 0) { + // No free range + return null; + } + mAvailableUidRanges.clear(uidRangeIndex); + int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange; + range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1); + mAppRanges.put(info.processName, info.uid, range); + } + return range; + } + + @GuardedBy("ProcessList.this.mService") + void freeUidRangeLocked(ApplicationInfo info) { + // Find the UID range + IsolatedUidRange range = mAppRanges.get(info.processName, info.uid); + if (range != null) { + // Map back to starting uid + final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange; + // Mark it as available in the underlying bitset + mAvailableUidRanges.set(uidRangeIndex); + // And the map + mAppRanges.remove(info.processName, info.uid); + } + } + } + + /** + * The available isolated UIDs for processes that are not spawned from an application zygote. + */ + @VisibleForTesting + IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID, + Process.LAST_ISOLATED_UID); + + /** + * An allocator for isolated UID ranges for apps that use an application zygote. + */ + @VisibleForTesting + IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator = + new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, + Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE); /** * Processes that are being forcibly torn down. @@ -1505,6 +1635,67 @@ public final class ProcessList { } } + @GuardedBy("mService") + public void killAppZygoteIfNeededLocked(AppZygote appZygote) { + final ApplicationInfo appInfo = appZygote.getAppInfo(); + ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); + if (zygoteProcesses.size() == 0) { // Only remove if no longer in use now + mAppZygotes.remove(appInfo.processName, appInfo.uid); + mAppZygoteProcesses.remove(appZygote); + mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo); + appZygote.stopZygote(); + } + } + + @GuardedBy("mService") + private void removeProcessFromAppZygoteLocked(final ProcessRecord app) { + // Free the isolated uid for this process + final IsolatedUidRange appUidRange = + mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info); + if (appUidRange != null) { + appUidRange.freeIsolatedUidLocked(app.uid); + } + + final AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid); + if (appZygote != null) { + ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); + zygoteProcesses.remove(app); + if (zygoteProcesses.size() == 0) { + Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG); + msg.obj = appZygote; + mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS); + } + } + } + + private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) { + synchronized (mService) { + AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid); + final ArrayList<ProcessRecord> zygoteProcessList; + if (appZygote == null) { + final int userId = UserHandle.getUserId(app.info.uid); + final IsolatedUidRange uidRange = + mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info); + // Allocate an isolated UID out of this range for the Zygote itself + final int zygoteIsolatedUid = uidRange.allocateIsolatedUidLocked(userId); + appZygote = new AppZygote(app.info, zygoteIsolatedUid); + mAppZygotes.put(app.info.processName, app.info.uid, appZygote); + zygoteProcessList = new ArrayList<ProcessRecord>(); + mAppZygoteProcesses.put(appZygote, zygoteProcessList); + } else { + mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote); + zygoteProcessList = mAppZygoteProcesses.get(appZygote); + } + // Note that we already add the app to mAppZygoteProcesses here; + // this is so that another thread can't come in and kill the zygote + // before we've even tried to start the process. If the process launch + // goes wrong, we'll clean this up in removeProcessNameLocked() + zygoteProcessList.add(app); + + return appZygote; + } + } + private Process.ProcessStartResult startProcess(String hostingType, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, @@ -1525,6 +1716,15 @@ public final class ProcessList { app.info.dataDir, null, app.info.packageName, packageNames, visibleVolIds, new String[] {PROC_START_SEQ_IDENT + app.startSeq}); + } else if (hostingType.equals("app_zygote")) { + final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); + + startResult = appZygote.getProcess().start(entryPoint, + app.processName, uid, uid, gids, runtimeFlags, mountExternal, + app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, + app.info.dataDir, null, app.info.packageName, + packageNames, visibleVolIds, + new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, @@ -1614,13 +1814,6 @@ public final class ProcessList { app.addPackage(info.packageName, info.versionCode, mService.mProcessStats); checkSlow(startTime, "startProcess: done, added package to proc"); return app; - } else if (app.getActiveInstrumentation() != null) { - // We don't want to kill running instrumentation. - if (DEBUG_PROCESSES) { - Slog.v(TAG_PROCESSES, "Instrumentation already running: " + app); - } - checkSlow(startTime, "startProcess: keep instrumentation proc"); - return app; } // An application record is attached to a previous process, @@ -1636,8 +1829,9 @@ public final class ProcessList { ? hostingName.flattenToShortString() : null; if (app == null) { + final boolean fromAppZygote = "app_zygote".equals(hostingType); checkSlow(startTime, "startProcess: creating new process record"); - app = newProcessRecordLocked(info, processName, isolated, isolatedUid); + app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote); if (app == null) { Slog.w(TAG, "Failed making new process record for " + processName + "/" + info.uid + " isolated=" + isolated); @@ -2010,29 +2204,31 @@ public final class ProcessList { } @GuardedBy("mService") + private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, + boolean fromAppZygote) { + if (!fromAppZygote) { + // Allocate an isolated UID from the global range + return mGlobalIsolatedUids; + } else { + return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(info); + } + } + + @GuardedBy("mService") final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, - boolean isolated, int isolatedUid) { + boolean isolated, int isolatedUid, boolean fromAppZygote) { String proc = customProcess != null ? customProcess : info.processName; final int userId = UserHandle.getUserId(info.uid); int uid = info.uid; if (isolated) { if (isolatedUid == 0) { - int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1; - while (true) { - if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID - || mNextIsolatedProcessUid > LAST_ISOLATED_UID) { - mNextIsolatedProcessUid = FIRST_ISOLATED_UID; - } - uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); - mNextIsolatedProcessUid++; - if (mIsolatedProcesses.indexOfKey(uid) < 0) { - // No process for this uid, use it. - break; - } - stepsLeft--; - if (stepsLeft <= 0) { - return null; - } + IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, fromAppZygote); + if (uidRange == null) { + return null; + } + uid = uidRange.allocateIsolatedUidLocked(userId); + if (uid == -1) { + return null; } } else { // Special case for startIsolatedProcess (internal only), where @@ -2100,6 +2296,13 @@ public final class ProcessList { old.uidRecord = null; } mIsolatedProcesses.remove(uid); + mGlobalIsolatedUids.freeIsolatedUidLocked(uid); + // Remove the (expected) ProcessRecord from the app zygote + final ProcessRecord record = expecting != null ? expecting : old; + if (record != null && record.appZygote) { + removeProcessFromAppZygoteLocked(record); + } + return old; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 6f0a562eb819..0d0824a74cdd 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -76,6 +76,7 @@ final class ProcessRecord implements WindowProcessListener { private final ActivityManagerService mService; // where we came from final ApplicationInfo info; // all about the first app in the process final boolean isolated; // true if this is a special isolated process + final boolean appZygote; // true if this is forked from the app zygote final int uid; // uid of process; may be different from 'info' if isolated final int userId; // user of process. final String processName; // name of the process @@ -559,6 +560,8 @@ final class ProcessRecord implements WindowProcessListener { mService = _service; info = _info; isolated = _info.uid != _uid; + appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID + && UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID); uid = _uid; userId = UserHandle.getUserId(_uid); processName = _processName; diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 52ecccaa7367..78b3c15500ea 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -17,13 +17,6 @@ package com.android.server.display; import android.annotation.Nullable; -import android.app.ActivityManager; -import android.app.ActivityManager.StackInfo; -import android.app.ActivityTaskManager; -import android.app.IActivityTaskManager; -import android.app.TaskStackListener; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManagerInternal; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; @@ -34,8 +27,6 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PowerManager; -import android.os.Process; -import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.util.EventLog; @@ -43,15 +34,14 @@ import android.util.MathUtils; import android.util.Slog; import android.util.TimeUtils; -import com.android.internal.os.BackgroundThread; import com.android.server.EventLogTags; -import com.android.server.LocalServices; import java.io.PrintWriter; class AutomaticBrightnessController { private static final String TAG = "AutomaticBrightnessController"; + private static final boolean DEBUG = false; private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false; // If true, enables the use of the screen auto-brightness adjustment setting. @@ -76,8 +66,6 @@ class AutomaticBrightnessController { private static final int MSG_UPDATE_AMBIENT_LUX = 1; private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2; private static final int MSG_INVALIDATE_SHORT_TERM_MODEL = 3; - private static final int MSG_UPDATE_FOREGROUND_APP = 4; - private static final int MSG_UPDATE_FOREGROUND_APP_SYNC = 5; // Length of the ambient light horizon used to calculate the long term estimate of ambient // light. @@ -138,8 +126,6 @@ class AutomaticBrightnessController { private final HysteresisLevels mAmbientBrightnessThresholds; private final HysteresisLevels mScreenBrightnessThresholds; - private boolean mLoggingEnabled; - // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. // May be 0 if no warm-up is required. @@ -206,19 +192,6 @@ class AutomaticBrightnessController { private float mShortTermModelAnchor; private float SHORT_TERM_MODEL_THRESHOLD_RATIO = 0.6f; - // Context-sensitive brightness configurations require keeping track of the foreground app's - // package name and category, which is done by registering a TaskStackListener to call back to - // us onTaskStackChanged, and then using the ActivityTaskManager to get the foreground app's - // package namd and PackageManager to get its category (so might as well cache them). - private int mUserId; - private String mForegroundAppPackageName; - private String mPendingForegroundAppPackageName; - private @ApplicationInfo.Category int mForegroundAppCategory; - private @ApplicationInfo.Category int mPendingForegroundAppCategory; - private TaskStackListenerImpl mTaskStackListener; - private IActivityTaskManager mActivityTaskManager; - private PackageManagerInternal mPackageManagerInternal; - public AutomaticBrightnessController(Callbacks callbacks, Looper looper, SensorManager sensorManager, BrightnessMappingStrategy mapper, int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, @@ -253,42 +226,6 @@ class AutomaticBrightnessController { if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) { mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } - - mUserId = ActivityManager.getCurrentUser(); - mActivityTaskManager = ActivityTaskManager.getService(); - mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); - mTaskStackListener = new TaskStackListenerImpl(); - mForegroundAppPackageName = null; - mPendingForegroundAppPackageName = null; - mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; - mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; - } - - /** - * Enable/disable logging. - * - * @param loggingEnabled - * Whether logging should be on/off. - * - * @return Whether the method succeeded or not. - */ - public boolean setLoggingEnabled(boolean loggingEnabled) { - if (mLoggingEnabled == loggingEnabled) { - return false; - } - mBrightnessMapper.setLoggingEnabled(loggingEnabled); - mLoggingEnabled = loggingEnabled; - return true; - } - - /** - * Update the current user's ID. - * - * @param userId - * The current user's ID. - */ - public void onSwitchUser(int userId) { - mUserId = userId; } public int getAutomaticScreenBrightness() { @@ -353,7 +290,7 @@ class AutomaticBrightnessController { } final int oldPolicy = mDisplayPolicy; mDisplayPolicy = policy; - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "Display policy transitioning from " + oldPolicy + " to " + policy); } if (!isInteractivePolicy(policy) && isInteractivePolicy(oldPolicy)) { @@ -380,7 +317,7 @@ class AutomaticBrightnessController { mBrightnessMapper.addUserDataPoint(mAmbientLux, brightness); mShortTermModelValid = true; mShortTermModelAnchor = mAmbientLux; - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "ShortTermModel: anchor=" + mShortTermModelAnchor); } return true; @@ -393,7 +330,7 @@ class AutomaticBrightnessController { } private void invalidateShortTermModel() { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "ShortTermModel: invalidate user data"); } mShortTermModelValid = false; @@ -446,11 +383,7 @@ class AutomaticBrightnessController { pw.println(" mBrightnessAdjustmentSampleOldLux=" + mBrightnessAdjustmentSampleOldLux); pw.println(" mBrightnessAdjustmentSampleOldBrightness=" + mBrightnessAdjustmentSampleOldBrightness); - pw.println(" mUserId=" + mUserId); - pw.println(" mForegroundAppPackageName=" + mForegroundAppPackageName); - pw.println(" mPendingForegroundAppPackageName=" + mPendingForegroundAppPackageName); - pw.println(" mForegroundAppCategory=" + mForegroundAppCategory); - pw.println(" mPendingForegroundAppCategory=" + mPendingForegroundAppCategory); + pw.println(" mShortTermModelValid=" + mShortTermModelValid); pw.println(); mBrightnessMapper.dump(pw); @@ -466,7 +399,6 @@ class AutomaticBrightnessController { mLightSensorEnabled = true; mLightSensorEnableTime = SystemClock.uptimeMillis(); mCurrentLightSensorRate = mInitialLightSensorRate; - registerForegroundAppUpdater(); mSensorManager.registerListener(mLightSensorListener, mLightSensor, mCurrentLightSensorRate * 1000, mHandler); return true; @@ -479,7 +411,6 @@ class AutomaticBrightnessController { mAmbientLightRingBuffer.clear(); mCurrentLightSensorRate = -1; mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX); - unregisterForegroundAppUpdater(); mSensorManager.unregisterListener(mLightSensorListener); } return false; @@ -510,7 +441,7 @@ class AutomaticBrightnessController { private void adjustLightSensorRate(int lightSensorRate) { // if the light sensor rate changed, update the sensor listener if (lightSensorRate != mCurrentLightSensorRate) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "adjustLightSensorRate: " + "previousRate=" + mCurrentLightSensorRate + ", " + "currentRate=" + lightSensorRate); @@ -527,7 +458,7 @@ class AutomaticBrightnessController { } private void setAmbientLux(float lux) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "setAmbientLux(" + lux + ")"); } if (lux < 0) { @@ -545,7 +476,7 @@ class AutomaticBrightnessController { final float maxAmbientLux = mShortTermModelAnchor + mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO; if (minAmbientLux < mAmbientLux && mAmbientLux < maxAmbientLux) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "ShortTermModel: re-validate user data, ambient lux is " + minAmbientLux + " < " + mAmbientLux + " < " + maxAmbientLux); } @@ -559,7 +490,7 @@ class AutomaticBrightnessController { } private float calculateAmbientLux(long now, long horizon) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "calculateAmbientLux(" + now + ", " + horizon + ")"); } final int N = mAmbientLightRingBuffer.size(); @@ -578,7 +509,7 @@ class AutomaticBrightnessController { break; } } - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=(" + mAmbientLightRingBuffer.getTime(endIndex) + ", " + mAmbientLightRingBuffer.getLux(endIndex) + ")"); @@ -596,7 +527,7 @@ class AutomaticBrightnessController { final long startTime = eventTime - now; float weight = calculateWeight(startTime, endTime); float lux = mAmbientLightRingBuffer.getLux(i); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "calculateAmbientLux: [" + startTime + ", " + endTime + "]: " + "lux=" + lux + ", " + "weight=" + weight); @@ -605,7 +536,7 @@ class AutomaticBrightnessController { sum += lux * weight; endTime = startTime; } - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "calculateAmbientLux: " + "totalWeight=" + totalWeight + ", " + "newAmbientLux=" + (sum / totalWeight)); @@ -660,7 +591,7 @@ class AutomaticBrightnessController { final long timeWhenSensorWarmedUp = mLightSensorWarmUpTimeConfig + mLightSensorEnableTime; if (time < timeWhenSensorWarmedUp) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "updateAmbientLux: Sensor not ready yet: " + "time=" + time + ", " + "timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp); @@ -671,7 +602,7 @@ class AutomaticBrightnessController { } setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS)); mAmbientLuxValid = true; - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "updateAmbientLux: Initializing: " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); @@ -699,10 +630,10 @@ class AutomaticBrightnessController { && fastAmbientLux <= mAmbientDarkeningThreshold && nextDarkenTransition <= time)) { setAmbientLux(fastAmbientLux); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "updateAmbientLux: " + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " - + "mBrighteningLuxThreshold=" + mAmbientBrighteningThreshold + ", " + + "mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); } @@ -719,7 +650,7 @@ class AutomaticBrightnessController { // weighted ambient lux or not. nextTransitionTime = nextTransitionTime > time ? nextTransitionTime : time + mNormalLightSensorRate; - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for " + nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime)); } @@ -731,8 +662,7 @@ class AutomaticBrightnessController { return; } - float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName, - mForegroundAppCategory); + float value = mBrightnessMapper.getBrightness(mAmbientLux); int newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); @@ -743,7 +673,7 @@ class AutomaticBrightnessController { if (mScreenAutoBrightness != -1 && newScreenAutoBrightness > mScreenDarkeningThreshold && newScreenAutoBrightness < mScreenBrighteningThreshold) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold); } @@ -751,7 +681,8 @@ class AutomaticBrightnessController { } if (mScreenAutoBrightness != newScreenAutoBrightness) { - if (mLoggingEnabled) { + + if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: " + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + "newScreenAutoBrightness=" + newScreenAutoBrightness); @@ -787,11 +718,18 @@ class AutomaticBrightnessController { BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS); } + private void cancelBrightnessAdjustmentSample() { + if (mBrightnessAdjustmentSamplePending) { + mBrightnessAdjustmentSamplePending = false; + mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE); + } + } + private void collectBrightnessAdjustmentSample() { if (mBrightnessAdjustmentSamplePending) { mBrightnessAdjustmentSamplePending = false; if (mAmbientLuxValid && mScreenAutoBrightness >= 0) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "Auto-brightness adjustment changed by user: " + "lux=" + mAmbientLux + ", " + "brightness=" + mScreenAutoBrightness + ", " + @@ -807,68 +745,6 @@ class AutomaticBrightnessController { } } - // Register a TaskStackListener to call back to us onTaskStackChanged, so we can update the - // foreground app's package name and category and correct the brightness accordingly. - private void registerForegroundAppUpdater() { - try { - mActivityTaskManager.registerTaskStackListener(mTaskStackListener); - // This will not get called until the foreground app changes for the first time, so - // call it explicitly to get the current foreground app's info. - updateForegroundApp(); - } catch (RemoteException e) { - // Nothing to do. - } - } - - private void unregisterForegroundAppUpdater() { - try { - mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); - } catch (RemoteException e) { - // Nothing to do. - } - mForegroundAppPackageName = null; - mForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; - } - - // Set the foreground app's package name and category, so brightness can be corrected per app. - private void updateForegroundApp() { - // The ActivityTaskManager's lock tends to get contended, so this is done in a background - // thread and applied via this thread's handler synchronously. - BackgroundThread.getHandler().post(new Runnable() { - public void run() { - try { - // The foreground app is the top activity of the focused tasks stack. - final StackInfo info = mActivityTaskManager.getFocusedStackInfo(); - if (info == null || info.topActivity == null) { - return; - } - final String packageName = info.topActivity.getPackageName(); - // If the app didn't change, there's nothing to do. Otherwise, we have to - // update the category and re-apply the brightness correction. - if (mForegroundAppPackageName != null - && mForegroundAppPackageName.equals(packageName)) { - return; - } - mPendingForegroundAppPackageName = packageName; - ApplicationInfo app = mPackageManagerInternal.getApplicationInfo(packageName, - 0 /* flags */, Process.SYSTEM_UID /* filterCallingUid */, mUserId); - mPendingForegroundAppCategory = app.category; - mHandler.sendEmptyMessage(MSG_UPDATE_FOREGROUND_APP_SYNC); - } catch (RemoteException e) { - // Nothing to do. - } - } - }); - } - - private void updateForegroundAppSync() { - mForegroundAppPackageName = mPendingForegroundAppPackageName; - mPendingForegroundAppPackageName = null; - mForegroundAppCategory = mPendingForegroundAppCategory; - mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; - updateAutoBrightness(true /* sendUpdate */); - } - private final class AutomaticBrightnessHandler extends Handler { public AutomaticBrightnessHandler(Looper looper) { super(looper, null, true /*async*/); @@ -888,14 +764,6 @@ class AutomaticBrightnessController { case MSG_INVALIDATE_SHORT_TERM_MODEL: invalidateShortTermModel(); break; - - case MSG_UPDATE_FOREGROUND_APP: - updateForegroundApp(); - break; - - case MSG_UPDATE_FOREGROUND_APP_SYNC: - updateForegroundAppSync(); - break; } } } @@ -916,15 +784,6 @@ class AutomaticBrightnessController { } }; - // Call back whenever the tasks stack changes, which includes tasks being created, removed, and - // moving to top. - class TaskStackListenerImpl extends TaskStackListener { - @Override - public void onTaskStackChanged() { - mHandler.sendEmptyMessage(MSG_UPDATE_FOREGROUND_APP); - } - } - /** Callbacks to request updates to the display's power state. */ interface Callbacks { void updateBrightness(); diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index 9fce644d6c4b..76c191d5e9ea 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -17,11 +17,9 @@ package com.android.server.display; import android.annotation.Nullable; -import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.hardware.display.BrightnessConfiguration; -import android.hardware.display.BrightnessCorrection; import android.os.PowerManager; import android.util.MathUtils; import android.util.Pair; @@ -44,12 +42,11 @@ import java.util.Arrays; */ public abstract class BrightnessMappingStrategy { private static final String TAG = "BrightnessMappingStrategy"; + private static final boolean DEBUG = false; private static final float LUX_GRAD_SMOOTHING = 0.25f; private static final float MAX_GRAD = 1.0f; - protected boolean mLoggingEnabled; - private static final Plog PLOG = Plog.createSystemPlog(TAG); @Nullable @@ -164,22 +161,6 @@ public abstract class BrightnessMappingStrategy { } /** - * Enable/disable logging. - * - * @param loggingEnabled - * Whether logging should be on/off. - * - * @return Whether the method succeeded or not. - */ - public boolean setLoggingEnabled(boolean loggingEnabled) { - if (mLoggingEnabled == loggingEnabled) { - return false; - } - mLoggingEnabled = loggingEnabled; - return true; - } - - /** * Sets the {@link BrightnessConfiguration}. * * @param config The new configuration. If {@code null} is passed, the default configuration is @@ -189,33 +170,15 @@ public abstract class BrightnessMappingStrategy { public abstract boolean setBrightnessConfiguration(@Nullable BrightnessConfiguration config); /** - * Returns the desired brightness of the display based on the current ambient lux, including - * any context-related corrections. - * - * The returned brightness will be in the range [0, 1.0], where 1.0 is the display at max - * brightness and 0 is the display at minimum brightness. - * - * @param lux The current ambient brightness in lux. - * @param packageName the foreground app package name. - * @param category the foreground app package category. - * @return The desired brightness of the display normalized to the range [0, 1.0]. - */ - public abstract float getBrightness(float lux, String packageName, - @ApplicationInfo.Category int category); - - /** * Returns the desired brightness of the display based on the current ambient lux. * - * The returned brightness wil be in the range [0, 1.0], where 1.0 is the display at max + * The returned brightness will be in the range [0, 1.0], where 1.0 is the display at max * brightness and 0 is the display at minimum brightness. * * @param lux The current ambient brightness in lux. - * * @return The desired brightness of the display normalized to the range [0, 1.0]. */ - public float getBrightness(float lux) { - return getBrightness(lux, null /* packageName */, ApplicationInfo.CATEGORY_UNDEFINED); - } + public abstract float getBrightness(float lux); /** * Returns the current auto-brightness adjustment. @@ -276,13 +239,13 @@ public abstract class BrightnessMappingStrategy { public abstract void dump(PrintWriter pw); - protected float normalizeAbsoluteBrightness(int brightness) { + private static float normalizeAbsoluteBrightness(int brightness) { brightness = MathUtils.constrain(brightness, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); return (float) brightness / PowerManager.BRIGHTNESS_ON; } - private Pair<float[], float[]> insertControlPoint( + private static Pair<float[], float[]> insertControlPoint( float[] luxLevels, float[] brightnessLevels, float lux, float brightness) { final int idx = findInsertionPoint(luxLevels, lux); final float[] newLuxLevels; @@ -315,7 +278,7 @@ public abstract class BrightnessMappingStrategy { * This assumes that {@code arr} is sorted. If all values in {@code arr} are greater * than val, then it will return the length of arr as the insertion point. */ - private int findInsertionPoint(float[] arr, float val) { + private static int findInsertionPoint(float[] arr, float val) { for (int i = 0; i < arr.length; i++) { if (val <= arr[i]) { return i; @@ -324,8 +287,8 @@ public abstract class BrightnessMappingStrategy { return arr.length; } - private void smoothCurve(float[] lux, float[] brightness, int idx) { - if (mLoggingEnabled) { + private static void smoothCurve(float[] lux, float[] brightness, int idx) { + if (DEBUG) { PLOG.logCurve("unsmoothed curve", lux, brightness); } float prevLux = lux[idx]; @@ -360,19 +323,19 @@ public abstract class BrightnessMappingStrategy { prevBrightness = newBrightness; brightness[i] = newBrightness; } - if (mLoggingEnabled) { + if (DEBUG) { PLOG.logCurve("smoothed curve", lux, brightness); } } - private float permissibleRatio(float currLux, float prevLux) { + private static float permissibleRatio(float currLux, float prevLux) { return MathUtils.exp(MAX_GRAD * (MathUtils.log(currLux + LUX_GRAD_SMOOTHING) - MathUtils.log(prevLux + LUX_GRAD_SMOOTHING))); } - protected float inferAutoBrightnessAdjustment(float maxGamma, float desiredBrightness, - float currentBrightness) { + private static float inferAutoBrightnessAdjustment(float maxGamma, + float desiredBrightness, float currentBrightness) { float adjustment = 0; float gamma = Float.NaN; // Extreme edge cases: use a simpler heuristic, as proper gamma correction around the edges @@ -392,7 +355,7 @@ public abstract class BrightnessMappingStrategy { adjustment = -MathUtils.log(gamma) / MathUtils.log(maxGamma); } adjustment = MathUtils.constrain(adjustment, -1, +1); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "inferAutoBrightnessAdjustment: " + maxGamma + "^" + -adjustment + "=" + MathUtils.pow(maxGamma, -adjustment) + " == " + gamma); Slog.d(TAG, "inferAutoBrightnessAdjustment: " + currentBrightness + "^" + gamma + "=" + @@ -401,16 +364,16 @@ public abstract class BrightnessMappingStrategy { return adjustment; } - protected Pair<float[], float[]> getAdjustedCurve(float[] lux, float[] brightness, + private static Pair<float[], float[]> getAdjustedCurve(float[] lux, float[] brightness, float userLux, float userBrightness, float adjustment, float maxGamma) { float[] newLux = lux; float[] newBrightness = Arrays.copyOf(brightness, brightness.length); - if (mLoggingEnabled) { + if (DEBUG) { PLOG.logCurve("unadjusted curve", newLux, newBrightness); } adjustment = MathUtils.constrain(adjustment, -1, 1); float gamma = MathUtils.pow(maxGamma, -adjustment); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "getAdjustedCurve: " + maxGamma + "^" + -adjustment + "=" + MathUtils.pow(maxGamma, -adjustment) + " == " + gamma); } @@ -419,7 +382,7 @@ public abstract class BrightnessMappingStrategy { newBrightness[i] = MathUtils.pow(newBrightness[i], gamma); } } - if (mLoggingEnabled) { + if (DEBUG) { PLOG.logCurve("gamma adjusted curve", newLux, newBrightness); } if (userLux != -1) { @@ -427,7 +390,7 @@ public abstract class BrightnessMappingStrategy { userBrightness); newLux = curve.first; newBrightness = curve.second; - if (mLoggingEnabled) { + if (DEBUG) { PLOG.logCurve("gamma and user adjusted curve", newLux, newBrightness); // This is done for comparison. curve = insertControlPoint(lux, brightness, userLux, userBrightness); @@ -477,7 +440,7 @@ public abstract class BrightnessMappingStrategy { mAutoBrightnessAdjustment = 0; mUserLux = -1; mUserBrightness = -1; - if (mLoggingEnabled) { + if (DEBUG) { PLOG.start("simple mapping strategy"); } computeSpline(); @@ -489,8 +452,7 @@ public abstract class BrightnessMappingStrategy { } @Override - public float getBrightness(float lux, String packageName, - @ApplicationInfo.Category int category) { + public float getBrightness(float lux) { return mSpline.interpolate(lux); } @@ -505,7 +467,7 @@ public abstract class BrightnessMappingStrategy { if (adjustment == mAutoBrightnessAdjustment) { return false; } - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " + adjustment); PLOG.start("auto-brightness adjustment"); @@ -523,7 +485,7 @@ public abstract class BrightnessMappingStrategy { @Override public void addUserDataPoint(float lux, float brightness) { float unadjustedBrightness = getUnadjustedBrightness(lux); - if (mLoggingEnabled) { + if (DEBUG){ Slog.d(TAG, "addUserDataPoint: (" + lux + "," + brightness + ")"); PLOG.start("add user data point") .logPoint("user data point", lux, brightness) @@ -532,7 +494,7 @@ public abstract class BrightnessMappingStrategy { float adjustment = inferAutoBrightnessAdjustment(mMaxGamma, brightness /* desiredBrightness */, unadjustedBrightness /* currentBrightness */); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "addUserDataPoint: " + mAutoBrightnessAdjustment + " => " + adjustment); } @@ -545,7 +507,7 @@ public abstract class BrightnessMappingStrategy { @Override public void clearUserDataPoints() { if (mUserLux != -1) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "clearUserDataPoints: " + mAutoBrightnessAdjustment + " => 0"); PLOG.start("clear user data points") .logPoint("user data point", mUserLux, mUserBrightness); @@ -652,7 +614,7 @@ public abstract class BrightnessMappingStrategy { mBacklightToNitsSpline = Spline.createSpline(normalizedBacklight, nits); mDefaultConfig = config; - if (mLoggingEnabled) { + if (DEBUG) { PLOG.start("physical mapping strategy"); } mConfig = config; @@ -667,7 +629,7 @@ public abstract class BrightnessMappingStrategy { if (config.equals(mConfig)) { return false; } - if (mLoggingEnabled) { + if (DEBUG) { PLOG.start("brightness configuration"); } mConfig = config; @@ -676,17 +638,9 @@ public abstract class BrightnessMappingStrategy { } @Override - public float getBrightness(float lux, String packageName, - @ApplicationInfo.Category int category) { + public float getBrightness(float lux) { float nits = mBrightnessSpline.interpolate(lux); float backlight = mNitsToBacklightSpline.interpolate(nits); - // Correct the brightness according to the current application and its category, but - // only if no user data point is set (as this will oevrride the user setting). - if (mUserLux == -1) { - backlight = correctBrightness(backlight, packageName, category); - } else if (mLoggingEnabled) { - Slog.d(TAG, "user point set, correction not applied"); - } return backlight; } @@ -701,7 +655,7 @@ public abstract class BrightnessMappingStrategy { if (adjustment == mAutoBrightnessAdjustment) { return false; } - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " + adjustment); PLOG.start("auto-brightness adjustment"); @@ -719,7 +673,7 @@ public abstract class BrightnessMappingStrategy { @Override public void addUserDataPoint(float lux, float brightness) { float unadjustedBrightness = getUnadjustedBrightness(lux); - if (mLoggingEnabled) { + if (DEBUG){ Slog.d(TAG, "addUserDataPoint: (" + lux + "," + brightness + ")"); PLOG.start("add user data point") .logPoint("user data point", lux, brightness) @@ -728,7 +682,7 @@ public abstract class BrightnessMappingStrategy { float adjustment = inferAutoBrightnessAdjustment(mMaxGamma, brightness /* desiredBrightness */, unadjustedBrightness /* currentBrightness */); - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "addUserDataPoint: " + mAutoBrightnessAdjustment + " => " + adjustment); } @@ -741,7 +695,7 @@ public abstract class BrightnessMappingStrategy { @Override public void clearUserDataPoints() { if (mUserLux != -1) { - if (mLoggingEnabled) { + if (DEBUG) { Slog.d(TAG, "clearUserDataPoints: " + mAutoBrightnessAdjustment + " => 0"); PLOG.start("clear user data points") .logPoint("user data point", mUserLux, mUserBrightness); @@ -804,21 +758,5 @@ public abstract class BrightnessMappingStrategy { Spline spline = Spline.createSpline(curve.first, curve.second); return mNitsToBacklightSpline.interpolate(spline.interpolate(lux)); } - - private float correctBrightness(float brightness, String packageName, int category) { - if (packageName != null) { - BrightnessCorrection correction = mConfig.getCorrectionByPackageName(packageName); - if (correction != null) { - return correction.apply(brightness); - } - } - if (category != ApplicationInfo.CATEGORY_UNDEFINED) { - BrightnessCorrection correction = mConfig.getCorrectionByCategory(category); - if (correction != null) { - return correction.apply(brightness); - } - } - return brightness; - } } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index b1ba05c035b3..0a1a9a20e0da 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2144,14 +2144,6 @@ public final class DisplayManagerService extends SystemService { mContext.getPackageName()); } - void setAutoBrightnessLoggingEnabled(boolean enabled) { - if (mDisplayPowerController != null) { - synchronized (mSyncRoot) { - mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled); - } - } - } - private boolean validatePackageName(int uid, String packageName) { if (packageName != null) { String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index abbfc7b18f94..27cad1eece09 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -17,9 +17,14 @@ package com.android.server.display; import android.content.Intent; +import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.os.ShellCommand; +import android.util.Slog; import java.io.PrintWriter; +import java.lang.NumberFormatException; class DisplayManagerShellCommand extends ShellCommand { private static final String TAG = "DisplayManagerShellCommand"; @@ -41,10 +46,6 @@ class DisplayManagerShellCommand extends ShellCommand { return setBrightness(); case "reset-brightness-configuration": return resetBrightnessConfiguration(); - case "ab-logging-enable": - return setAutoBrightnessLoggingEnabled(true); - case "ab-logging-disable": - return setAutoBrightnessLoggingEnabled(false); default: return handleDefaultCommands(cmd); } @@ -61,10 +62,6 @@ class DisplayManagerShellCommand extends ShellCommand { pw.println(" Sets the current brightness to BRIGHTNESS (a number between 0 and 1)."); pw.println(" reset-brightness-configuration"); pw.println(" Reset the brightness to its default configuration."); - pw.println(" ab-logging-enable"); - pw.println(" Enable auto-brightness logging."); - pw.println(" ab-logging-disable"); - pw.println(" Disable auto-brightness logging."); pw.println(); Intent.printIntentArgsHelp(pw , ""); } @@ -92,9 +89,4 @@ class DisplayManagerShellCommand extends ShellCommand { mService.resetBrightnessConfiguration(); return 0; } - - private int setAutoBrightnessLoggingEnabled(boolean enabled) { - mService.setAutoBrightnessLoggingEnabled(enabled); - return 0; - } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index c9ed9f7cea43..249270bfda7e 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -523,9 +523,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call public void onSwitchUser(@UserIdInt int newUserId) { handleSettingsChange(true /* userSwitch */); mBrightnessTracker.onSwitchUser(newUserId); - if (mAutomaticBrightnessController != null) { - mAutomaticBrightnessController.onSwitchUser(newUserId); - } } public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats( @@ -1839,10 +1836,4 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mHandler.sendMessage(msg); } } - - void setAutoBrightnessLoggingEnabled(boolean enabled) { - if (mAutomaticBrightnessController != null) { - mAutomaticBrightnessController.setLoggingEnabled(enabled); - } - } } diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index 9aec43b6eaed..89cef621a55d 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -16,6 +16,13 @@ package com.android.server.display; +import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.XmlUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + import android.annotation.Nullable; import android.graphics.Point; import android.hardware.display.BrightnessConfiguration; @@ -23,20 +30,13 @@ import android.hardware.display.WifiDisplay; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; +import android.util.Pair; import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.Xml; import android.view.Display; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FastXmlSerializer; -import com.android.internal.util.XmlUtils; - -import libcore.io.IoUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -50,9 +50,12 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; +import libcore.io.IoUtils; + /** * Manages persistent state recorded by the display manager service as an XML file. * Caller must acquire lock on the data store before accessing it. @@ -107,9 +110,14 @@ final class PersistentDataStore { private static final String TAG_BRIGHTNESS_CONFIGURATIONS = "brightness-configurations"; private static final String TAG_BRIGHTNESS_CONFIGURATION = "brightness-configuration"; + private static final String TAG_BRIGHTNESS_CURVE = "brightness-curve"; + private static final String TAG_BRIGHTNESS_POINT = "brightness-point"; private static final String ATTR_USER_SERIAL = "user-serial"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_TIME_STAMP = "timestamp"; + private static final String ATTR_LUX = "lux"; + private static final String ATTR_NITS = "nits"; + private static final String ATTR_DESCRIPTION = "description"; // Remembered Wifi display devices. private ArrayList<WifiDisplay> mRememberedWifiDisplays = new ArrayList<WifiDisplay>(); @@ -638,8 +646,7 @@ final class PersistentDataStore { } try { - BrightnessConfiguration config = - BrightnessConfiguration.loadFromXml(parser); + BrightnessConfiguration config = loadConfigurationFromXml(parser); if (userSerial >= 0 && config != null) { mConfigurations.put(userSerial, config); if (timeStamp != -1) { @@ -656,6 +663,56 @@ final class PersistentDataStore { } } + private static BrightnessConfiguration loadConfigurationFromXml(XmlPullParser parser) + throws IOException, XmlPullParserException { + final int outerDepth = parser.getDepth(); + String description = null; + Pair<float[], float[]> curve = null; + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if (TAG_BRIGHTNESS_CURVE.equals(parser.getName())) { + description = parser.getAttributeValue(null, ATTR_DESCRIPTION); + curve = loadCurveFromXml(parser); + } + } + if (curve == null) { + return null; + } + final BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder( + curve.first, curve.second); + builder.setDescription(description); + return builder.build(); + } + + private static Pair<float[], float[]> loadCurveFromXml(XmlPullParser parser) + throws IOException, XmlPullParserException { + final int outerDepth = parser.getDepth(); + List<Float> luxLevels = new ArrayList<>(); + List<Float> nitLevels = new ArrayList<>(); + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if (TAG_BRIGHTNESS_POINT.equals(parser.getName())) { + luxLevels.add(loadFloat(parser.getAttributeValue(null, ATTR_LUX))); + nitLevels.add(loadFloat(parser.getAttributeValue(null, ATTR_NITS))); + } + } + final int N = luxLevels.size(); + float[] lux = new float[N]; + float[] nits = new float[N]; + for (int i = 0; i < N; i++) { + lux[i] = luxLevels.get(i); + nits[i] = nitLevels.get(i); + } + return Pair.create(lux, nits); + } + + private static float loadFloat(String val) { + try { + return Float.parseFloat(val); + } catch (NullPointerException | NumberFormatException e) { + Slog.e(TAG, "Failed to parse float loading brightness config", e); + return Float.NEGATIVE_INFINITY; + } + } + public void saveToXml(XmlSerializer serializer) throws IOException { for (int i = 0; i < mConfigurations.size(); i++) { final int userSerial = mConfigurations.keyAt(i); @@ -671,11 +728,27 @@ final class PersistentDataStore { if (timestamp != -1) { serializer.attribute(null, ATTR_TIME_STAMP, Long.toString(timestamp)); } - config.saveToXml(serializer); + saveConfigurationToXml(serializer, config); serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATION); } } + private static void saveConfigurationToXml(XmlSerializer serializer, + BrightnessConfiguration config) throws IOException { + serializer.startTag(null, TAG_BRIGHTNESS_CURVE); + if (config.getDescription() != null) { + serializer.attribute(null, ATTR_DESCRIPTION, config.getDescription()); + } + final Pair<float[], float[]> curve = config.getCurve(); + for (int i = 0; i < curve.first.length; i++) { + serializer.startTag(null, TAG_BRIGHTNESS_POINT); + serializer.attribute(null, ATTR_LUX, Float.toString(curve.first[i])); + serializer.attribute(null, ATTR_NITS, Float.toString(curve.second[i])); + serializer.endTag(null, TAG_BRIGHTNESS_POINT); + } + serializer.endTag(null, TAG_BRIGHTNESS_CURVE); + } + public void dump(final PrintWriter pw, final String prefix) { for (int i = 0; i < mConfigurations.size(); i++) { final int userSerial = mConfigurations.keyAt(i); diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index d154830062f6..1f0f94a7bf0b 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import android.annotation.IntDef; import android.hardware.hdmi.HdmiDeviceInfo; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -316,7 +317,7 @@ final class Constants { * <p>When ARC is initiated, this port will be used to turn on ARC. */ static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT = - "persist.sys.hdmi.property_sytem_audio_device_arc_port"; + "persist.sys.hdmi.property_sytem_audio_device_arc_port"; /** * Property to strip local audio of amplifier and use local speaker diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 3845954bc0d4..9690ba877c1e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -95,6 +95,11 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice { startQueuedActions(); } + @Override + protected int findKeyReceiverAddress() { + return Constants.ADDR_TV; + } + @VisibleForTesting protected void systemAudioControlOnPowerOn( int systemAudioOnPowerOnProp, boolean lastSystemAudioControlStatus) { diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index f468c0bf6652..3420b263eac5 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE; + import static com.android.server.hdmi.Constants.DISABLED; import static com.android.server.hdmi.Constants.ENABLED; import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE; @@ -67,6 +68,7 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; + import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; @@ -76,6 +78,9 @@ import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback; import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import com.android.server.hdmi.HdmiCecLocalDevice.PendingActionClearedCallback; + +import libcore.util.EmptyArray; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -85,7 +90,6 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import libcore.util.EmptyArray; /** * Provides a service for sending and processing HDMI control messages, @@ -1469,12 +1473,12 @@ public class HdmiControlService extends SystemService { @Override public boolean getSystemAudioMode() { + // TODO(shubang): handle getSystemAudioMode() for all device types enforceAccessPermission(); HdmiCecLocalDeviceTv tv = tv(); - if (tv == null) { - return false; - } - return tv.isSystemAudioActivated(); + HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); + return (tv != null && tv.isSystemAudioActivated()) + || (audioSystem != null && audioSystem.isSystemAudioActivated()); } @Override diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index d51da995a37d..052d5797c1e7 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -40,6 +40,7 @@ import android.media.AudioPlaybackConfiguration; import android.media.AudioSystem; import android.media.IAudioService; import android.media.IRemoteVolumeController; +import android.media.Session2Token; import android.media.session.IActiveSessionsListener; import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; @@ -895,6 +896,21 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override + public void notifySession2Created(Session2Token sessionToken) throws RemoteException { + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + try { + if (DEBUG) { + Log.d(TAG, "Session2 is created " + sessionToken); + } + // TODO: Keep the session. + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override public List<IBinder> getSessions(ComponentName componentName, int userId) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 0d6dadfb1ad8..af55605975ca 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -270,14 +270,12 @@ import java.util.concurrent.TimeUnit; * enforcement. * * <p> - * This class uses 2-3 locks to synchronize state: + * This class uses 2 locks to synchronize state: * <ul> * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall * rules). * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such * as network policies). - * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks - * must be held. * </ul> * * <p> @@ -419,7 +417,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final Object mUidRulesFirstLock = new Object(); final Object mNetworkPoliciesSecondLock = new Object(); - @GuardedBy("allLocks") volatile boolean mSystemReady; + @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) + volatile boolean mSystemReady; @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground; @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower; @@ -558,7 +557,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final ServiceThread mUidEventThread; - @GuardedBy("allLocks") + @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"}) private final AtomicFile mPolicyFile; private final AppOpsManager mAppOps; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c2c88258b067..4f21db159625 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -765,8 +765,7 @@ public class NotificationManagerService extends SystemService { .addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, nv.rank) .addTaggedData(MetricsEvent.NOTIFICATION_SHADE_COUNT, nv.count) .addTaggedData(MetricsEvent.NOTIFICATION_ACTION_IS_SMART, - (Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION - == action.getSemanticAction()) ? 1 : 0) + action.isContextual() ? 1 : 0) .addTaggedData( MetricsEvent.NOTIFICATION_SMART_SUGGESTION_ASSISTANT_GENERATED, generatedByAssistant ? 1 : 0)); @@ -970,7 +969,7 @@ public class NotificationManagerService extends SystemService { r.getNumSmartActionsAdded()) .addTaggedData( MetricsEvent.NOTIFICATION_SMART_SUGGESTION_ASSISTANT_GENERATED, - r.getSuggestionsGeneratedByAssistant()); + r.getSuggestionsGeneratedByAssistant() ? 1 : 0); mMetricsLogger.write(logMaker); } } @@ -2642,6 +2641,9 @@ public class NotificationManagerService extends SystemService { // Zen mConditionProviders.onPackagesChanged(true, packages, uids); + // Snoozing + mSnoozeHelper.clearData(UserHandle.getUserId(uid), packageName); + // Reset notification preferences if (!fromApp) { mPreferencesHelper.onPackagesChanged( @@ -5698,19 +5700,17 @@ public class NotificationManagerService extends SystemService { } int indexBefore = findNotificationRecordIndexLocked(record); boolean interceptBefore = record.isIntercepted(); - float contactAffinityBefore = record.getContactAffinity(); int visibilityBefore = record.getPackageVisibilityOverride(); recon.applyChangesLocked(record); applyZenModeLocked(record); mRankingHelper.sort(mNotificationList); int indexAfter = findNotificationRecordIndexLocked(record); boolean interceptAfter = record.isIntercepted(); - float contactAffinityAfter = record.getContactAffinity(); int visibilityAfter = record.getPackageVisibilityOverride(); changed = indexBefore != indexAfter || interceptBefore != interceptAfter || visibilityBefore != visibilityAfter; if (interceptBefore && !interceptAfter - && Float.compare(contactAffinityBefore, contactAffinityAfter) != 0) { + && record.isNewEnoughForAlerting(System.currentTimeMillis())) { buzzBeepBlinkLocked(record); } } diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index e2c64ca459a8..9942f5920c9e 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -92,6 +92,8 @@ public final class NotificationRecord { static final String TAG = "NotificationRecord"; static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private static final int MAX_LOGTAG_LENGTH = 35; + // the period after which a notification is updated where it can make sound + private static final int MAX_SOUND_DELAY_MS = 2000; final StatusBarNotification sbn; IActivityManager mAm; UriGrantsManagerInternal mUgmInternal; @@ -125,7 +127,8 @@ public final class NotificationRecord { private long mVisibleSinceMs; // The most recent update time, or the creation time if no updates. - private long mUpdateTimeMs; + @VisibleForTesting + final long mUpdateTimeMs; // The most recent interruption time, or the creation time if no updates. Differs from the // above value because updates are filtered based on whether they actually interrupted the @@ -165,7 +168,7 @@ public final class NotificationRecord { private String mChannelIdLogTag; /** * This list contains system generated smart actions from NAS, app-generated smart actions are - * stored in Notification.actions marked as SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION. + * stored in Notification.actions with isContextual() set to true. */ private ArrayList<Notification.Action> mSystemGeneratedSmartActions; private ArrayList<CharSequence> mSmartReplies; @@ -826,6 +829,10 @@ public final class NotificationRecord { return mIntercept; } + public boolean isNewEnoughForAlerting(long now) { + return getFreshnessMs(now) <= MAX_SOUND_DELAY_MS; + } + public void setHidden(boolean hidden) { mHidden = hidden; } diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index 2b581d601ad5..abc98412e126 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -17,6 +17,7 @@ package com.android.server.notification; import android.annotation.NonNull; import android.app.AlarmManager; +import android.app.Notification; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -163,7 +164,6 @@ public class SnoozeHelper { mSnoozedNotifications.get(userId).get(pkg); if (recordsForPkg != null) { final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet(); - String key = null; for (Map.Entry<String, NotificationRecord> record : records) { final StatusBarNotification sbn = record.getValue().sbn; if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) { @@ -305,6 +305,30 @@ public class SnoozeHelper { } } + protected void clearData(int userId, String pkg) { + ArrayMap<String, ArrayMap<String, NotificationRecord>> records = + mSnoozedNotifications.get(userId); + if (records == null) { + return; + } + ArrayMap<String, NotificationRecord> pkgRecords = records.get(pkg); + if (pkgRecords == null) { + return; + } + for (int i = pkgRecords.size() - 1; i >= 0; i--) { + final NotificationRecord r = pkgRecords.removeAt(i); + if (r != null) { + mPackages.remove(r.getKey()); + mUsers.remove(r.getKey()); + final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId); + mAm.cancel(pi); + MetricsLogger.action(r.getLogMaker() + .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) + .setType(MetricsProto.MetricsEvent.TYPE_DISMISS)); + } + } + } + private PendingIntent createPendingIntent(String pkg, String key, int userId) { return PendingIntent.getBroadcast(mContext, REQUEST_CODE_REPOST, diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5c4c1bac2419..fe89be6f73c4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8549,16 +8549,16 @@ public class PackageManagerService extends IPackageManager.Stub } /** - * Returns if full apk verification can be skipped for the whole package, including the splits. + * Returns if forced apk verification can be skipped for the whole package, including splits. */ - private boolean canSkipFullPackageVerification(PackageParser.Package pkg) { - if (!canSkipFullApkVerification(pkg.baseCodePath)) { + private boolean canSkipForcedPackageVerification(PackageParser.Package pkg) { + if (!canSkipForcedApkVerification(pkg.baseCodePath)) { return false; } // TODO: Allow base and splits to be verified individually. if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (int i = 0; i < pkg.splitCodePaths.length; i++) { - if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) { + if (!canSkipForcedApkVerification(pkg.splitCodePaths[i])) { return false; } } @@ -8567,14 +8567,17 @@ public class PackageManagerService extends IPackageManager.Stub } /** - * Returns if full apk verification can be skipped, depending on current FSVerity setup and + * Returns if forced apk verification can be skipped, depending on current FSVerity setup and * whether the apk contains signed root hash. Note that the signer's certificate still needs to * match one in a trusted source, and should be done separately. */ - private boolean canSkipFullApkVerification(String apkPath) { - final byte[] rootHashObserved; + private boolean canSkipForcedApkVerification(String apkPath) { + if (!PackageManagerServiceUtils.isLegacyApkVerityMode()) { + return VerityUtils.hasFsverity(apkPath); + } + try { - rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath); + final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath); if (rootHashObserved == null) { return false; // APK does not contain Merkle tree root hash. } @@ -8746,7 +8749,7 @@ public class PackageManagerService extends IPackageManager.Stub // in verified partition, or can be verified on access (when apk verity is enabled). In both // cases, only data in Signing Block is verified instead of the whole file. final boolean skipVerify = scanSystemPartition - || (forceCollect && canSkipFullPackageVerification(pkg)); + || (forceCollect && canSkipForcedPackageVerification(pkg)); collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify); // Reset profile if the application version is changed diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index c7928633eef6..2060aef37044 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.content.Context.CONTEXT_RESTRICTED; import static android.content.Context.DISPLAY_SERVICE; import static android.content.Context.WINDOW_SERVICE; +import static android.content.pm.PackageManager.FEATURE_HDMI_CEC; import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.FEATURE_WATCH; @@ -126,6 +127,7 @@ import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManager; +import android.hardware.hdmi.HdmiAudioSystemClient; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; @@ -195,6 +197,7 @@ import com.android.internal.R; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.os.RoSystemProperties; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; import com.android.internal.policy.PhoneWindow; @@ -373,6 +376,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private ScreenshotHelper mScreenshotHelper; private boolean mHasFeatureWatch; private boolean mHasFeatureLeanback; + private boolean mHasFeatureHdmiCec; // Assigned on main thread, accessed on UI thread volatile VrManagerInternal mVrManagerInternal; @@ -1453,7 +1457,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { */ private HdmiControl getHdmiControl() { if (null == mHdmiControl) { - if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { + if (!mHasFeatureHdmiCec) { return null; } HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService( @@ -1689,6 +1693,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH); mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK); + mHasFeatureHdmiCec = mContext.getPackageManager().hasSystemFeature(FEATURE_HDMI_CEC); mAccessibilityShortcutController = new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId); mLogger = new MetricsLogger(); @@ -4116,6 +4121,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void dispatchDirectAudioEvent(KeyEvent event) { + // When System Audio Mode is off, volume keys received by AVR can be either consumed by AVR + // or forwarded to the TV. It's up to Amplifier manufacturer’s implementation. + HdmiControlManager hdmiControlManager = getHdmiControlManager(); + if (null != hdmiControlManager + && !hdmiControlManager.getSystemAudioMode() + && shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff()) { + HdmiAudioSystemClient audioSystemClient = hdmiControlManager.getAudioSystemClient(); + if (audioSystemClient != null) { + audioSystemClient.sendKeyEvent( + event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN); + return; + } + } if (event.getAction() != KeyEvent.ACTION_DOWN) { return; } @@ -4123,6 +4141,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_FROM_KEY; String pkgName = mContext.getOpPackageName(); + switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: try { @@ -4154,6 +4173,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Nullable + private HdmiControlManager getHdmiControlManager() { + if (!mHasFeatureHdmiCec) { + return null; + } + return (HdmiControlManager) mContext.getSystemService(HdmiControlManager.class); + } + + private boolean shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff() { + return RoSystemProperties.CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF; + } + void dispatchMediaKeyWithWakeLock(KeyEvent event) { if (DEBUG_INPUT) { Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java index 8c3f04f3b8a8..4b5e76497f62 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerService.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java @@ -17,8 +17,6 @@ package com.android.server.rollback; import android.content.Context; -import android.os.SELinux; -import android.util.Log; import com.android.server.SystemService; @@ -30,8 +28,6 @@ import com.android.server.SystemService; */ public final class RollbackManagerService extends SystemService { - private static final String TAG = "RollbackManager"; - private RollbackManagerServiceImpl mService; public RollbackManagerService(Context context) { @@ -41,12 +37,6 @@ public final class RollbackManagerService extends SystemService { @Override public void onStart() { mService = new RollbackManagerServiceImpl(getContext()); - - // TODO: Set up sepolicy to allow publishing the service. - if (SELinux.isSELinuxEnforced()) { - Log.w(TAG, "RollbackManager disabled pending selinux policy updates"); - } else { - publishBinderService(Context.ROLLBACK_SERVICE, mService); - } + publishBinderService(Context.ROLLBACK_SERVICE, mService); } } diff --git a/services/core/java/com/android/server/rollback/TEST_MAPPING b/services/core/java/com/android/server/rollback/TEST_MAPPING new file mode 100644 index 000000000000..c1d95ac85c23 --- /dev/null +++ b/services/core/java/com/android/server/rollback/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "RollbackTest" + } + ] +} diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index d5286b9ae87c..a50ae8431cb0 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -947,6 +947,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid); + boolean knownToBeDead = false; if (wpc != null && wpc.hasThread()) { try { if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0 @@ -965,6 +966,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // If a dead object exception was thrown -- fall through to // restart the application. + knownToBeDead = true; } // Suppress transition until the new activity becomes ready, otherwise the keyguard can @@ -978,7 +980,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // ATMS lock held. final Message msg = PooledLambda.obtainMessage( ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName, - r.info.applicationInfo, true, "activity", r.intent.getComponent()); + r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent()); mService.mH.sendMessage(msg); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index efce379fdf01..42121ca08696 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -639,7 +639,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - ActivityTaskManagerService(Context context) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public ActivityTaskManagerService(Context context) { mContext = context; mFactoryTest = FactoryTest.getMode(); mSystemThread = ActivityThread.currentActivityThread(); diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 49a3186be9b4..d6f161645327 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -18,7 +18,6 @@ package com.android.server.wm; import android.annotation.NonNull; import android.annotation.Nullable; -import android.graphics.Point; import android.graphics.Rect; import android.util.proto.ProtoOutputStream; import android.view.InsetsState; @@ -26,8 +25,10 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.InsetsSource; import android.view.InsetsSourceControl; +import android.view.ViewRootImpl; import com.android.internal.util.function.TriConsumer; +import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; @@ -106,8 +107,8 @@ class InsetsSourceProvider { mTmpRect.inset(mWin.mGivenContentInsets); } mSource.setFrame(mTmpRect); - setServerVisible(mWin.isVisible() && !mWin.mGivenInsetsPending); - + setServerVisible(mWin.wouldBeVisibleIfPolicyIgnored() && mWin.mPolicyVisibility + && !mWin.mGivenInsetsPending); } void updateControlForTarget(@Nullable WindowState target) { @@ -115,15 +116,15 @@ class InsetsSourceProvider { return; } if (target == null) { - revokeControl(); + // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields. + mWin.cancelAnimation(); return; } mAdapter = new ControlAdapter(); mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter, - false /* TODO hidden */); + !mClientVisible /* hidden */); mControllingWin = target; mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash); - setClientVisible(InsetsState.getDefaultVisibly(mSource.getType())); } boolean onInsetsModified(WindowState caller, InsetsSource modifiedSource) { @@ -135,7 +136,12 @@ class InsetsSourceProvider { } private void setClientVisible(boolean clientVisible) { + if (mClientVisible == clientVisible) { + return; + } mClientVisible = clientVisible; + mDisplayContent.mWmService.mH.sendMessage(PooledLambda.obtainMessage( + DisplayContent::layoutAndAssignWindowLayersIfNeeded, mDisplayContent)); updateVisibility(); } @@ -152,13 +158,8 @@ class InsetsSourceProvider { return mControl; } - void revokeControl() { - if (mControllingWin != null) { - - // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields. - mWin.cancelAnimation(); - } - setClientVisible(InsetsState.getDefaultVisibly(mSource.getType())); + boolean isClientVisible() { + return !ViewRootImpl.USE_NEW_INSETS || mClientVisible; } private class ControlAdapter implements AnimationAdapter { @@ -186,6 +187,7 @@ class InsetsSourceProvider { public void onAnimationCancelled(SurfaceControl animationLeash) { if (mAdapter == this) { mStateController.notifyControlRevoked(mControllingWin, InsetsSourceProvider.this); + setClientVisible(InsetsState.getDefaultVisibly(mSource.getType())); mControl = null; mControllingWin = null; mAdapter = null; diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 8e119bb195d6..cc57b932092c 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -218,5 +218,11 @@ class InsetsStateController { void dump(String prefix, PrintWriter pw) { pw.println(prefix + "WindowInsetsStateController"); mState.dump(prefix + " ", pw); + pw.println(prefix + " " + "Control map:"); + for (int i = mTypeWinControlMap.size() - 1; i >= 0; i--) { + pw.print(prefix + " "); + pw.println(InsetsState.typeToString(mTypeWinControlMap.keyAt(i)) + " -> " + + mTypeWinControlMap.valueAt(i)); + } } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index d85fdb03e4a6..937c9d9fc809 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -187,7 +187,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, - Surface outSurface, InsetsState outInsetsState) { + SurfaceControl outSurfaceControl, InsetsState outInsetsState) { if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " + Binder.getCallingPid()); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); @@ -195,7 +195,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { requestedWidth, requestedHeight, viewFlags, flags, frameNumber, outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, outStableInsets, outsets, outBackdropFrame, cutout, - mergedConfiguration, outSurface, outInsetsState); + mergedConfiguration, outSurfaceControl, outInsetsState); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 9a56606aee7f..2d3e3aee4b7f 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -111,6 +111,7 @@ class TaskSnapshotSurface implements StartingSurface { private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s"; private final Window mWindow; private final Surface mSurface; + private SurfaceControl mSurfaceControl; private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; private final WindowManagerService mService; @@ -136,7 +137,7 @@ class TaskSnapshotSurface implements StartingSurface { final Window window = new Window(); final IWindowSession session = WindowManagerGlobal.getWindowSession(); window.setSession(session); - final Surface surface = new Surface(); + final SurfaceControl surfaceControl = new SurfaceControl(); final Rect tmpRect = new Rect(); final DisplayCutout.ParcelableWrapper tmpCutout = new DisplayCutout.ParcelableWrapper(); final Rect tmpFrame = new Rect(); @@ -213,14 +214,14 @@ class TaskSnapshotSurface implements StartingSurface { // Local call. } final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window, - surface, snapshot, layoutParams.getTitle(), backgroundColor, statusBarColor, + surfaceControl, snapshot, layoutParams.getTitle(), backgroundColor, statusBarColor, navigationBarColor, sysUiVis, windowFlags, windowPrivateFlags, taskBounds, currentOrientation); window.setOuter(snapshotSurface); try { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrame, tmpRect, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect, tmpRect, - tmpCutout, tmpMergedConfiguration, surface, mTmpInsetsState); + tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState); } catch (RemoteException e) { // Local call. } @@ -230,15 +231,16 @@ class TaskSnapshotSurface implements StartingSurface { } @VisibleForTesting - TaskSnapshotSurface(WindowManagerService service, Window window, Surface surface, + TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, int backgroundColor, int statusBarColor, int navigationBarColor, int sysUiVis, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation) { mService = service; + mSurface = new Surface(); mHandler = new Handler(mService.mH.getLooper()); mSession = WindowManagerGlobal.getWindowSession(); mWindow = window; - mSurface = surface; + mSurfaceControl = surfaceControl; mSnapshot = snapshot; mTitle = title; mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE); @@ -281,6 +283,8 @@ class TaskSnapshotSurface implements StartingSurface { private void drawSnapshot() { final GraphicBuffer buffer = mSnapshot.getSnapshot(); + mSurface.copyFrom(mSurfaceControl); + if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch=" + mSizeMismatch); if (mSizeMismatch) { @@ -310,13 +314,14 @@ class TaskSnapshotSurface implements StartingSurface { if (!mSurface.isValid()) { throw new IllegalStateException("mSurface does not hold a valid surface."); } - final SurfaceSession session = new SurfaceSession(mSurface); + final SurfaceSession session = new SurfaceSession(); // Keep a reference to it such that it doesn't get destroyed when finalized. mChildSurfaceControl = new SurfaceControl.Builder(session) .setName(mTitle + " - task-snapshot-surface") .setBufferSize(buffer.getWidth(), buffer.getHeight()) .setFormat(buffer.getFormat()) + .setParent(mSurfaceControl) .build(); Surface surface = new Surface(); surface.copyFrom(mChildSurfaceControl); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f5f55e2ebf73..caa72fa62072 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1874,7 +1874,7 @@ public class WindowManagerService extends IWindowManager.Stub long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, - Surface outSurface, InsetsState outInsetsState) { + SurfaceControl outSurfaceControl, InsetsState outInsetsState) { int result = 0; boolean configChanged; final boolean hasStatusBarPermission = @@ -2047,7 +2047,7 @@ public class WindowManagerService extends IWindowManager.Stub result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility); try { - result = createSurfaceControl(outSurface, result, win, winAnimator); + result = createSurfaceControl(outSurfaceControl, result, win, winAnimator); } catch (Exception e) { displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); @@ -2078,7 +2078,7 @@ public class WindowManagerService extends IWindowManager.Stub // handled yet, or it might want to draw a last frame. If we already have a // surface, let the client use that, but don't create new surface at this point. Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface"); - winAnimator.mSurfaceController.getSurface(outSurface); + winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } else { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win); @@ -2086,7 +2086,7 @@ public class WindowManagerService extends IWindowManager.Stub try { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_" + win.mAttrs.getTitle()); - outSurface.release(); + outSurfaceControl.release(); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } @@ -2182,7 +2182,7 @@ public class WindowManagerService extends IWindowManager.Stub + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility + "\nRelayout returning frame=" + outFrame - + ", surface=" + outSurface); + + ", surface=" + outSurfaceControl); if (localLOGV || DEBUG_FOCUS) Slog.v( TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange); @@ -2252,7 +2252,7 @@ public class WindowManagerService extends IWindowManager.Stub return focusMayChange; } - private int createSurfaceControl(Surface outSurface, int result, WindowState win, + private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; @@ -2266,13 +2266,13 @@ public class WindowManagerService extends IWindowManager.Stub Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } if (surfaceController != null) { - surfaceController.getSurface(outSurface); - if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied"); + surfaceController.getSurfaceControl(outSurfaceControl); + if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurfaceControl + ": copied"); } else { // For some reason there isn't a surface. Clear the // caller's object so they see the same state. Slog.w(TAG_WM, "Failed to create surface control for " + win); - outSurface.release(); + outSurfaceControl.release(); } return result; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e78c12cfcc78..cd29b3c29248 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1373,12 +1373,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean isVisible() { - return wouldBeVisibleIfPolicyIgnored() && mPolicyVisibility; + return wouldBeVisibleIfPolicyIgnored() && mPolicyVisibility + // If we don't have a provider, this window isn't used as a window generating + // insets, so nobody can hide it over the inset APIs. + && (mInsetProvider == null || mInsetProvider.isClientVisible()); } /** - * @return True if the window would be visible if we'd ignore policy visibility, false - * otherwise. + * @return {@code true} if the window would be visible if we'd ignore policy visibility, + * {@code false} otherwise. */ boolean wouldBeVisibleIfPolicyIgnored() { return mHasSurface && !isParentWindowHidden() diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index ce627e23e6ee..c2a8e7efb5a5 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -478,8 +478,8 @@ class WindowSurfaceController { return mSurfaceControl.getHandle(); } - void getSurface(Surface outSurface) { - outSurface.copyFrom(mSurfaceControl); + void getSurfaceControl(SurfaceControl outSurfaceControl) { + outSurfaceControl.copyFrom(mSurfaceControl); } int getLayer() { diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java index b8723c520cf8..b682def9c224 100644 --- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.robolectric.Shadows.shadowOf; import static org.testng.Assert.expectThrows; @@ -192,6 +193,19 @@ public class BackupManagerServiceTest { /** Test that the service unregisters users when stopped. */ @Test + public void testStopServiceForUser_forRegisteredUser_tearsDownCorrectUser() throws Exception { + BackupManagerService backupManagerService = + createServiceAndRegisterUser(mUserOneId, mUserOneService); + backupManagerService.startServiceForUser(mUserTwoId, mUserTwoService); + + backupManagerService.stopServiceForUser(mUserOneId); + + verify(mUserOneService).tearDownService(); + verifyNoMoreInteractions(mUserTwoService); + } + + /** Test that the service unregisters users when stopped. */ + @Test public void testStopServiceForUser_forUnknownUser_doesNothing() throws Exception { BackupManagerService backupManagerService = createService(); diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java index bb60c27a2543..8d5c301d93e7 100644 --- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -829,7 +829,7 @@ public class UserBackupManagerServiceTest { public void testRequestBackup_whenNotProvisioned() throws Exception { mShadowContext.grantPermissions(android.Manifest.permission.BACKUP); UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks(); - backupManagerService.setProvisioned(false); + backupManagerService.setSetupComplete(false); int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0); @@ -848,7 +848,7 @@ public class UserBackupManagerServiceTest { setUpCurrentTransport(mTransportManager, mTransport.unregistered()); UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks(); backupManagerService.setEnabled(true); - backupManagerService.setProvisioned(true); + backupManagerService.setSetupComplete(true); int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0); @@ -868,7 +868,7 @@ public class UserBackupManagerServiceTest { setUpCurrentTransport(mTransportManager, mTransport); UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks(); backupManagerService.setEnabled(true); - backupManagerService.setProvisioned(true); + backupManagerService.setSetupComplete(true); // Haven't set PACKAGE_1 as eligible int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0); @@ -965,14 +965,13 @@ public class UserBackupManagerServiceTest { private UserBackupManagerService createBackupManagerServiceForRequestBackup() { UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks(); backupManagerService.setEnabled(true); - backupManagerService.setProvisioned(true); + backupManagerService.setSetupComplete(true); return backupManagerService; } /** - * Test verifying that {@link UserBackupManagerService#createAndInitializeService(Context, - * Trampoline, HandlerThread, File, File, TransportManager)} posts a transport registration task - * to the backup thread. + * Test verifying that creating a new instance posts a transport registration task to the backup + * thread. */ @Test public void testCreateAndInitializeService_postRegisterTransports() { @@ -992,9 +991,8 @@ public class UserBackupManagerServiceTest { } /** - * Test verifying that {@link UserBackupManagerService#createAndInitializeService(Context, - * Trampoline, HandlerThread, File, File, TransportManager)} does not directly register - * transports on the main thread. + * Test verifying that creating a new instance does not directly register transports on the main + * thread. */ @Test public void testCreateAndInitializeService_doesNotRegisterTransportsSynchronously() { @@ -1013,11 +1011,7 @@ public class UserBackupManagerServiceTest { verify(mTransportManager, never()).registerTransports(); } - /** - * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(Context, Trampoline, HandlerThread, File, - * File, TransportManager)}. - */ + /** Test checking non-null argument on instance creation. */ @Test public void testCreateAndInitializeService_withNullContext_throws() { expectThrows( @@ -1033,11 +1027,7 @@ public class UserBackupManagerServiceTest { mTransportManager)); } - /** - * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(Context, Trampoline, HandlerThread, File, - * File, TransportManager)}. - */ + /** Test checking non-null argument on instance creation. */ @Test public void testCreateAndInitializeService_withNullTrampoline_throws() { expectThrows( @@ -1053,11 +1043,7 @@ public class UserBackupManagerServiceTest { mTransportManager)); } - /** - * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(Context, Trampoline, HandlerThread, File, - * File, TransportManager)}. - */ + /** Test checking non-null argument on instance creation. */ @Test public void testCreateAndInitializeService_withNullBackupThread_throws() { expectThrows( @@ -1073,11 +1059,7 @@ public class UserBackupManagerServiceTest { mTransportManager)); } - /** - * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(Context, Trampoline, HandlerThread, File, - * File, TransportManager)}. - */ + /** Test checking non-null argument on instance creation. */ @Test public void testCreateAndInitializeService_withNullStateDir_throws() { expectThrows( diff --git a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java new file mode 100644 index 000000000000..b56b5e6132d5 --- /dev/null +++ b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2018 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.backup.internal; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.Handler; +import android.os.HandlerThread; +import android.platform.test.annotations.Presubmit; +import android.provider.Settings; + +import com.android.server.backup.KeyValueBackupJob; +import com.android.server.backup.TransportManager; +import com.android.server.backup.UserBackupManagerService; +import com.android.server.backup.testing.BackupManagerServiceTestUtils; +import com.android.server.backup.testing.TestUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.io.File; + +/** + * Tests verifying the interaction between {@link SetupObserver} and {@link + * UserBackupManagerService}. + */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class SetupObserverTest { + private static final String TAG = "SetupObserverTest"; + private static final int USER_ID = 10; + + @Mock private TransportManager mTransportManager; + + private Context mContext; + private UserBackupManagerService mUserBackupManagerService; + private HandlerThread mHandlerThread; + + /** Setup state. */ + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mHandlerThread = BackupManagerServiceTestUtils.startSilentBackupThread(TAG); + mUserBackupManagerService = + BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks( + USER_ID, + mContext, + mHandlerThread, + new File(mContext.getDataDir(), "test1"), + new File(mContext.getDataDir(), "test2"), + mTransportManager); + } + + /** Test observer handles changes from not setup -> setup correctly. */ + @Test + public void testOnChange_whenNewlySetup_updatesState() throws Exception { + SetupObserver setupObserver = new SetupObserver(mUserBackupManagerService, new Handler()); + mUserBackupManagerService.setSetupComplete(false); + changeSetupCompleteSettingForUser(true, USER_ID); + + setupObserver.onChange(true); + + assertThat(mUserBackupManagerService.isSetupComplete()).isTrue(); + } + + /** Test observer handles changes from setup -> not setup correctly. */ + @Test + public void testOnChange_whenPreviouslySetup_doesNotUpdateState() throws Exception { + SetupObserver setupObserver = new SetupObserver(mUserBackupManagerService, new Handler()); + mUserBackupManagerService.setSetupComplete(true); + changeSetupCompleteSettingForUser(false, USER_ID); + + setupObserver.onChange(true); + + assertThat(mUserBackupManagerService.isSetupComplete()).isTrue(); + } + + /** Test observer handles changes from not setup -> not setup correctly. */ + @Test + public void testOnChange_whenNotPreviouslySetup_doesNotUpdateStateIfNoChange() + throws Exception { + SetupObserver setupObserver = new SetupObserver(mUserBackupManagerService, new Handler()); + mUserBackupManagerService.setSetupComplete(false); + changeSetupCompleteSettingForUser(false, USER_ID); + + setupObserver.onChange(true); + + assertThat(mUserBackupManagerService.isSetupComplete()).isFalse(); + } + + /** Test observer handles changes from not setup -> setup correctly. */ + @Test + public void testOnChange_whenNewlySetup_schedulesBackup() throws Exception { + SetupObserver setupObserver = new SetupObserver(mUserBackupManagerService, new Handler()); + mUserBackupManagerService.setSetupComplete(false); + changeSetupCompleteSettingForUser(true, USER_ID); + // Setup conditions for a full backup job to be scheduled. + mUserBackupManagerService.setEnabled(true); + mUserBackupManagerService.enqueueFullBackup("testPackage", /* lastBackedUp */ 0); + // Clear the handler of all pending tasks. This is to prevent the below assertion on the + // handler from encountering false positives due to other tasks being scheduled as part of + // setup work. + TestUtils.runToEndOfTasks(mHandlerThread.getLooper()); + + setupObserver.onChange(true); + + assertThat(KeyValueBackupJob.isScheduled()).isTrue(); + // Verifies that the full backup job is scheduled. The job is scheduled via a posted message + // on the backup handler so we verify that a message exists. + assertThat(mUserBackupManagerService.getBackupHandler().hasMessagesOrCallbacks()).isTrue(); + } + + private void changeSetupCompleteSettingForUser(boolean value, int userId) { + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, + value ? 1 : 0, + userId); + } +} diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 767eb60de4f8..6a10ff487d2d 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -29,6 +29,8 @@ import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.util.DebugUtils.valueToString; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + import static com.android.server.am.ActivityManagerInternalTest.CustomThread; import static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG; import static com.android.server.am.ActivityManagerService.Injector; @@ -69,6 +71,9 @@ import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import com.android.server.AppOpsService; +import com.android.server.am.ProcessList.IsolatedUidRange; +import com.android.server.am.ProcessList.IsolatedUidRangeAllocator; +import com.android.server.wm.ActivityTaskManagerService; import org.junit.After; import org.junit.Before; @@ -109,7 +114,7 @@ public class ActivityManagerServiceTest { UidRecord.CHANGE_ACTIVE }; - @Mock private Context mContext; + private Context mContext = getInstrumentation().getTargetContext(); @Mock private AppOpsService mAppOpsService; @Mock private PackageManager mPackageManager; @@ -128,8 +133,8 @@ public class ActivityManagerServiceTest { mInjector = new TestInjector(); mAms = new ActivityManagerService(mInjector); mAms.mWaitForNetworkTimeoutMs = 2000; - - when(mContext.getPackageManager()).thenReturn(mPackageManager); + mAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); + mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper()); } @After @@ -291,6 +296,113 @@ public class ActivityManagerServiceTest { } } + private void validateAppZygoteIsolatedUidRange(IsolatedUidRange uidRange) { + assertNotNull(uidRange); + assertTrue(uidRange.mFirstUid >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID + && uidRange.mFirstUid <= Process.LAST_APP_ZYGOTE_ISOLATED_UID); + assertTrue(uidRange.mLastUid >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID + && uidRange.mLastUid <= Process.LAST_APP_ZYGOTE_ISOLATED_UID); + assertTrue(uidRange.mLastUid > uidRange.mFirstUid + && ((uidRange.mLastUid - uidRange.mFirstUid + 1) + == Process.NUM_UIDS_PER_APP_ZYGOTE)); + } + + private void verifyUidRangesNoOverlap(IsolatedUidRange uidRange1, IsolatedUidRange uidRange2) { + IsolatedUidRange lowRange = uidRange1.mFirstUid <= uidRange2.mFirstUid ? uidRange1 : uidRange2; + IsolatedUidRange highRange = lowRange == uidRange1 ? uidRange2 : uidRange1; + + assertTrue(highRange.mFirstUid > lowRange.mLastUid); + } + + @Test + public void testIsolatedUidRangeAllocator() { + final IsolatedUidRangeAllocator allocator = mAms.mProcessList.mAppIsolatedUidRangeAllocator; + + // Create initial range + ApplicationInfo appInfo = new ApplicationInfo(); + appInfo.processName = "com.android.test.app"; + appInfo.uid = 10000; + final IsolatedUidRange range = allocator.getOrCreateIsolatedUidRangeLocked(appInfo); + validateAppZygoteIsolatedUidRange(range); + verifyIsolatedUidAllocator(range); + + // Create a second range + ApplicationInfo appInfo2 = new ApplicationInfo(); + appInfo2.processName = "com.android.test.app2"; + appInfo2.uid = 10001; + IsolatedUidRange range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2); + validateAppZygoteIsolatedUidRange(range2); + verifyIsolatedUidAllocator(range2); + + // Verify ranges don't overlap + verifyUidRangesNoOverlap(range, range2); + + // Free range, reallocate and verify + allocator.freeUidRangeLocked(appInfo2); + range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2); + validateAppZygoteIsolatedUidRange(range2); + verifyUidRangesNoOverlap(range, range2); + verifyIsolatedUidAllocator(range2); + + // Free both, then try to allocate the maximum number of UID ranges + allocator.freeUidRangeLocked(appInfo); + allocator.freeUidRangeLocked(appInfo2); + + int maxNumUidRanges = (Process.LAST_APP_ZYGOTE_ISOLATED_UID + - Process.FIRST_APP_ZYGOTE_ISOLATED_UID + 1) / Process.NUM_UIDS_PER_APP_ZYGOTE; + for (int i = 0; i < maxNumUidRanges; i++) { + appInfo = new ApplicationInfo(); + appInfo.uid = 10000 + i; + appInfo.processName = "com.android.test.app" + Integer.toString(i); + IsolatedUidRange uidRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo); + validateAppZygoteIsolatedUidRange(uidRange); + verifyIsolatedUidAllocator(uidRange); + } + + // Try to allocate another one and make sure it fails + appInfo = new ApplicationInfo(); + appInfo.uid = 9000; + appInfo.processName = "com.android.test.app.failed"; + IsolatedUidRange failedRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo); + + assertNull(failedRange); + } + + public void verifyIsolatedUid(ProcessList.IsolatedUidRange range, int uid) { + assertTrue(uid >= range.mFirstUid && uid <= range.mLastUid); + } + + public void verifyIsolatedUidAllocator(ProcessList.IsolatedUidRange range) { + int uid = range.allocateIsolatedUidLocked(0); + verifyIsolatedUid(range, uid); + + int uid2 = range.allocateIsolatedUidLocked(0); + verifyIsolatedUid(range, uid2); + assertTrue(uid2 != uid); + + // Free both + range.freeIsolatedUidLocked(uid); + range.freeIsolatedUidLocked(uid2); + + // Allocate the entire range + for (int i = 0; i < (range.mLastUid - range.mFirstUid + 1); ++i) { + uid = range.allocateIsolatedUidLocked(0); + verifyIsolatedUid(range, uid); + } + + // Ensure the next one fails + uid = range.allocateIsolatedUidLocked(0); + assertEquals(uid, -1); + } + + @Test + public void testGlobalIsolatedUidAllocator() { + final IsolatedUidRange globalUidRange = mAms.mProcessList.mGlobalIsolatedUids; + assertEquals(globalUidRange.mFirstUid, Process.FIRST_ISOLATED_UID); + assertEquals(globalUidRange.mLastUid, Process.LAST_ISOLATED_UID); + verifyIsolatedUidAllocator(globalUidRange); + } + @Test public void testBlockStateForUid() { final UidRecord uidRec = new UidRecord(TEST_UID, null /* atmInternal */); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java index 65e640f5f73c..1458266089c5 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java @@ -825,4 +825,24 @@ public class NotificationRecordTest extends UiServiceTestCase { assertNotEquals(-1, record.getLastAudiblyAlertedMs()); } + + @Test + public void testIsNewEnoughForAlerting_new() { + StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, groupId /* group */); + NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); + + assertTrue(record.isNewEnoughForAlerting(record.mUpdateTimeMs)); + } + + @Test + public void testIsNewEnoughForAlerting_old() { + StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, groupId /* group */); + NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); + + assertFalse(record.isNewEnoughForAlerting(record.mUpdateTimeMs + (1000 * 60 * 60))); + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java index 49f134fdeac0..174c5fa6a51e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -299,6 +299,59 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertEquals(1, mSnoozeHelper.getSnoozed(UserHandle.USER_SYSTEM, "pkg").size()); } + @Test + public void testClearData() { + // snooze 2 from same package + NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); + mSnoozeHelper.snooze(r, 1000); + mSnoozeHelper.snooze(r2, 1000); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey())); + + // clear data + mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg"); + + // nothing snoozed; alarms canceled + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey())); + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r2.sbn.getPackageName(), r2.getKey())); + // twice for initial snooze, twice for canceling the snooze + verify(mAm, times(4)).cancel(any(PendingIntent.class)); + } + + @Test + public void testClearData_otherRecordsUntouched() { + // 2 packages, 2 users + NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL); + NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM); + mSnoozeHelper.snooze(r, 1000); + mSnoozeHelper.snooze(r2, 1000); + mSnoozeHelper.snooze(r3, 1000); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_ALL, r2.sbn.getPackageName(), r2.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey())); + + // clear data + mSnoozeHelper.clearData(UserHandle.USER_SYSTEM, "pkg"); + + assertFalse(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_ALL, r2.sbn.getPackageName(), r2.getKey())); + assertTrue(mSnoozeHelper.isSnoozed( + UserHandle.USER_SYSTEM, r3.sbn.getPackageName(), r3.getKey())); + // once for each initial snooze, once for canceling one snooze + verify(mAm, times(4)).cancel(any(PendingIntent.class)); + } + private NotificationRecord getNotificationRecord(String pkg, int id, String tag, UserHandle user, String groupKey, boolean groupSummary) { Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID) diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java index 624ef9ba1653..ca815eca9a1f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java @@ -39,6 +39,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.Surface; +import android.view.SurfaceControl; import androidx.test.filters.SmallTest; @@ -65,7 +66,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer, ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */); - mSurface = new TaskSnapshotSurface(mWm, new Window(), new Surface(), snapshot, "Test", + mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test", Color.WHITE, Color.RED, Color.BLUE, sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 7f7803463543..c09cd46a6c04 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90; +import static android.view.InsetsState.TYPE_TOP_BAR; import static android.view.Surface.ROTATION_0; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; @@ -31,6 +32,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVE import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; @@ -56,6 +58,7 @@ import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Size; import android.view.DisplayCutout; +import android.view.InsetsSource; import android.view.SurfaceControl; import android.view.WindowManager; @@ -326,6 +329,20 @@ public class WindowStateTests extends WindowTestsBase { } @Test + public void testVisibleWithInsetsProvider() throws Exception { + final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar"); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + topBar.mHasSurface = true; + assertTrue(topBar.isVisible()); + mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR) + .setWindow(topBar, null); + mDisplayContent.getInsetsStateController().onBarControllingWindowChanged(app); + mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR) + .onInsetsModified(app, new InsetsSource(TYPE_TOP_BAR)); + assertFalse(topBar.isVisible()); + } + + @Test public void testIsSelfOrAncestorWindowAnimating() { final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1"); diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 294b7509698b..f1e22819f501 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -1744,8 +1744,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), USB_GADGET_HAL_DEATH_COOKIE); mCurrentFunctions = UsbManager.FUNCTION_NONE; - mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); mCurrentUsbFunctionsRequested = true; + mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); } String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp index 91cec554d7cd..82056e9a33fe 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -34,6 +34,7 @@ cc_library_host_static { defaults: ["viewcompiler_defaults"], srcs: [ "dex_builder.cc", + "dex_layout_compiler.cc", "java_lang_builder.cc", "tinyxml_layout_parser.cc", "util.cc", diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp index 4449ea0f707e..d4f38ed148c9 100644 --- a/startop/view_compiler/dex_builder_test/Android.bp +++ b/startop/view_compiler/dex_builder_test/Android.bp @@ -14,16 +14,30 @@ // limitations under the License. // +genrule { + name: "generate_compiled_layout", + tools: [":viewcompiler"], + cmd: "$(location :viewcompiler) $(in) --dex --out $(out) --package android.startop.test", + srcs: ["res/layout/layout1.xml"], + out: [ + "layout1.dex", + ], +} + android_test { name: "dex-builder-test", - srcs: ["src/android/startop/test/DexBuilderTest.java"], + srcs: [ + "src/android/startop/test/DexBuilderTest.java", + "src/android/startop/test/LayoutCompilerTest.java", + ], sdk_version: "current", - data: [":generate_dex_testcases"], + data: [":generate_dex_testcases", ":generate_compiled_layout"], static_libs: [ "android-support-test", "guava", ], manifest: "AndroidManifest.xml", + resource_dirs: ["res"], test_config: "AndroidTest.xml", test_suites: ["general-tests"], } diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml index 6f90cf3b81a7..68d8fdc444d8 100644 --- a/startop/view_compiler/dex_builder_test/AndroidTest.xml +++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml @@ -25,6 +25,7 @@ <option name="cleanup" value="true" /> <option name="push" value="trivial.dex->/data/local/tmp/dex-builder-test/trivial.dex" /> <option name="push" value="simple.dex->/data/local/tmp/dex-builder-test/simple.dex" /> + <option name="push" value="layout1.dex->/data/local/tmp/dex-builder-test/layout1.dex" /> </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > diff --git a/startop/view_compiler/dex_builder_test/res/layout/layout1.xml b/startop/view_compiler/dex_builder_test/res/layout/layout1.xml new file mode 100644 index 000000000000..0f9375c6ebce --- /dev/null +++ b/startop/view_compiler/dex_builder_test/res/layout/layout1.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:orientation="vertical" + android:gravity="center"> + + <Button + android:layout_width="match_parent" + android:layout_height="match_parent"/> + <Button + android:layout_width="match_parent" + android:layout_height="match_parent"/> + + </LinearLayout> diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java new file mode 100644 index 000000000000..ce3ce8328559 --- /dev/null +++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.startop.test; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.view.View; +import com.google.common.io.ByteStreams; +import dalvik.system.InMemoryDexClassLoader; +import dalvik.system.PathClassLoader; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import org.junit.Assert; +import org.junit.Test; + +// Adding tests here requires changes in several other places. See README.md in +// the view_compiler directory for more information. +public class LayoutCompilerTest { + static ClassLoader loadDexFile(String filename) throws Exception { + return new PathClassLoader("/data/local/tmp/dex-builder-test/" + filename, + ClassLoader.getSystemClassLoader()); + } + + @Test + public void loadAndInflaterLayout1() throws Exception { + ClassLoader dex_file = loadDexFile("layout1.dex"); + Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView"); + Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class); + Context context = InstrumentationRegistry.getTargetContext(); + layout1.invoke(null, context, R.layout.layout1); + } +} diff --git a/startop/view_compiler/dex_layout_compiler.cc b/startop/view_compiler/dex_layout_compiler.cc new file mode 100644 index 000000000000..c68793d10399 --- /dev/null +++ b/startop/view_compiler/dex_layout_compiler.cc @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2018 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. + */ + +#include "dex_layout_compiler.h" +#include "layout_validation.h" + +#include "android-base/stringprintf.h" + +namespace startop { + +using android::base::StringPrintf; + +void LayoutValidationVisitor::VisitStartTag(const std::u16string& name) { + if (0 == name.compare(u"merge")) { + message_ = "Merge tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"include")) { + message_ = "Include tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"view")) { + message_ = "View tags are not supported"; + can_compile_ = false; + } + if (0 == name.compare(u"fragment")) { + message_ = "Fragment tags are not supported"; + can_compile_ = false; + } +} + +DexViewBuilder::DexViewBuilder(dex::MethodBuilder* method) + : method_{method}, + context_{dex::Value::Parameter(0)}, + resid_{dex::Value::Parameter(1)}, + inflater_{method->MakeRegister()}, + xml_{method->MakeRegister()}, + attrs_{method->MakeRegister()}, + classname_tmp_{method->MakeRegister()}, + xml_next_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser"), "next", + dex::Prototype{dex::TypeDescriptor::Int()})}, + try_create_view_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), "tryCreateView", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("java.lang.String"), + dex::TypeDescriptor::FromClassname("android.content.Context"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})}, + generate_layout_params_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "generateLayoutParams", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})}, + add_view_{method->dex_file()->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "addView", + dex::Prototype{ + dex::TypeDescriptor::Void(), + dex::TypeDescriptor::FromClassname("android.view.View"), + dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams")})}, + // The register stack starts with one register, which will be null for the root view. + register_stack_{{method->MakeRegister()}} {} + +void DexViewBuilder::Start() { + dex::DexBuilder* const dex = method_->dex_file(); + + // LayoutInflater inflater = LayoutInflater.from(context); + auto layout_inflater_from = dex->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), + "from", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), + dex::TypeDescriptor::FromClassname("android.content.Context")}); + method_->AddInstruction( + dex::Instruction::InvokeStaticObject(layout_inflater_from.id, /*dest=*/inflater_, context_)); + + // Resources res = context.getResources(); + auto context_type = dex::TypeDescriptor::FromClassname("android.content.Context"); + auto resources_type = dex::TypeDescriptor::FromClassname("android.content.res.Resources"); + auto get_resources = + dex->GetOrDeclareMethod(context_type, "getResources", dex::Prototype{resources_type}); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_resources.id, xml_, context_)); + + // XmlResourceParser xml = res.getLayout(resid); + auto xml_resource_parser_type = + dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser"); + auto get_layout = + dex->GetOrDeclareMethod(resources_type, + "getLayout", + dex::Prototype{xml_resource_parser_type, dex::TypeDescriptor::Int()}); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_layout.id, xml_, xml_, resid_)); + + // AttributeSet attrs = Xml.asAttributeSet(xml); + auto as_attribute_set = dex->GetOrDeclareMethod( + dex::TypeDescriptor::FromClassname("android.util.Xml"), + "asAttributeSet", + dex::Prototype{dex::TypeDescriptor::FromClassname("android.util.AttributeSet"), + dex::TypeDescriptor::FromClassname("org.xmlpull.v1.XmlPullParser")}); + method_->AddInstruction(dex::Instruction::InvokeStaticObject(as_attribute_set.id, attrs_, xml_)); + + // xml.next(); // start document + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); +} + +void DexViewBuilder::Finish() {} + +namespace { +std::string ResolveName(const std::string& name) { + if (name == "View") return "android.view.View"; + if (name == "ViewGroup") return "android.view.ViewGroup"; + if (name.find(".") == std::string::npos) { + return StringPrintf("android.widget.%s", name.c_str()); + } + return name; +} +} // namespace + +void DexViewBuilder::StartView(const std::string& name, bool is_viewgroup) { + bool const is_root_view = view_stack_.empty(); + + // xml.next(); // start tag + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); + + dex::Value view = AcquireRegister(); + // try to create the view using the factories + method_->BuildConstString(classname_tmp_, + name); // TODO: the need to fully qualify the classname + if (is_root_view) { + dex::Value null = AcquireRegister(); + method_->BuildConst4(null, 0); + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + try_create_view_.id, view, inflater_, null, classname_tmp_, context_, attrs_)); + ReleaseRegister(); + } else { + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + try_create_view_.id, view, inflater_, GetCurrentView(), classname_tmp_, context_, attrs_)); + } + auto label = method_->MakeLabel(); + // branch if not null + method_->AddInstruction( + dex::Instruction::OpWithArgs(dex::Instruction::Op::kBranchNEqz, /*dest=*/{}, view, label)); + + // If null, create the class directly. + method_->BuildNew(view, + dex::TypeDescriptor::FromClassname(ResolveName(name)), + dex::Prototype{dex::TypeDescriptor::Void(), + dex::TypeDescriptor::FromClassname("android.content.Context"), + dex::TypeDescriptor::FromClassname("android.util.AttributeSet")}, + context_, + attrs_); + + method_->AddInstruction( + dex::Instruction::OpWithArgs(dex::Instruction::Op::kBindLabel, /*dest=*/{}, label)); + + if (is_viewgroup) { + // Cast to a ViewGroup so we can add children later. + const ir::Type* view_group_def = method_->dex_file()->GetOrAddType( + dex::TypeDescriptor::FromClassname("android.view.ViewGroup").descriptor()); + method_->AddInstruction(dex::Instruction::Cast(view, dex::Value::Type(view_group_def->orig_index))); + } + + if (!is_root_view) { + // layout_params = parent.generateLayoutParams(attrs); + dex::Value layout_params{AcquireRegister()}; + method_->AddInstruction(dex::Instruction::InvokeVirtualObject( + generate_layout_params_.id, layout_params, GetCurrentView(), attrs_)); + view_stack_.push_back({view, layout_params}); + } else { + view_stack_.push_back({view, {}}); + } +} + +void DexViewBuilder::FinishView() { + if (view_stack_.size() == 1) { + method_->BuildReturn(GetCurrentView(), /*is_object=*/true); + } else { + // parent.add(view, layout_params) + method_->AddInstruction(dex::Instruction::InvokeVirtual( + add_view_.id, /*dest=*/{}, GetParentView(), GetCurrentView(), GetCurrentLayoutParams())); + // xml.next(); // end tag + method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_)); + } + PopViewStack(); +} + +dex::Value DexViewBuilder::AcquireRegister() { + top_register_++; + if (register_stack_.size() == top_register_) { + register_stack_.push_back(method_->MakeRegister()); + } + return register_stack_[top_register_]; +} + +void DexViewBuilder::ReleaseRegister() { top_register_--; } + +dex::Value DexViewBuilder::GetCurrentView() const { return view_stack_.back().view; } +dex::Value DexViewBuilder::GetCurrentLayoutParams() const { + return view_stack_.back().layout_params.value(); +} +dex::Value DexViewBuilder::GetParentView() const { + return view_stack_[view_stack_.size() - 2].view; +} + +void DexViewBuilder::PopViewStack() { + const auto& top = view_stack_.back(); + // release the layout params if we have them + if (top.layout_params.has_value()) { + ReleaseRegister(); + } + // Unconditionally release the view register. + ReleaseRegister(); + view_stack_.pop_back(); +} + +} // namespace startop
\ No newline at end of file diff --git a/startop/view_compiler/dex_layout_compiler.h b/startop/view_compiler/dex_layout_compiler.h new file mode 100644 index 000000000000..170a1a610297 --- /dev/null +++ b/startop/view_compiler/dex_layout_compiler.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2018 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. + */ + +#ifndef DEX_LAYOUT_COMPILER_H_ +#define DEX_LAYOUT_COMPILER_H_ + +#include "dex_builder.h" + +#include <codecvt> +#include <locale> +#include <string> +#include <vector> + +namespace startop { + +// This visitor does the actual view compilation, using a supplied builder. +template <typename Builder> +class LayoutCompilerVisitor { + public: + explicit LayoutCompilerVisitor(Builder* builder) : builder_{builder} {} + + void VisitStartDocument() { builder_->Start(); } + void VisitEndDocument() { builder_->Finish(); } + void VisitStartTag(const std::u16string& name) { + parent_stack_.push_back(ViewEntry{ + std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(name), {}}); + } + void VisitEndTag() { + auto entry = parent_stack_.back(); + parent_stack_.pop_back(); + + if (parent_stack_.empty()) { + GenerateCode(entry); + } else { + parent_stack_.back().children.push_back(entry); + } + } + + private: + struct ViewEntry { + std::string name; + std::vector<ViewEntry> children; + }; + + void GenerateCode(const ViewEntry& view) { + builder_->StartView(view.name, !view.children.empty()); + for (const auto& child : view.children) { + GenerateCode(child); + } + builder_->FinishView(); + } + + Builder* builder_; + + std::vector<ViewEntry> parent_stack_; +}; + +class DexViewBuilder { + public: + DexViewBuilder(dex::MethodBuilder* method); + + void Start(); + void Finish(); + void StartView(const std::string& name, bool is_viewgroup); + void FinishView(); + + private: + // Accessors for the stack of views that are under construction. + dex::Value AcquireRegister(); + void ReleaseRegister(); + dex::Value GetCurrentView() const; + dex::Value GetCurrentLayoutParams() const; + dex::Value GetParentView() const; + void PopViewStack(); + + dex::MethodBuilder* method_; + + // Registers used for code generation + dex::Value const context_; + dex::Value const resid_; + const dex::Value inflater_; + const dex::Value xml_; + const dex::Value attrs_; + const dex::Value classname_tmp_; + + const dex::MethodDeclData xml_next_; + const dex::MethodDeclData try_create_view_; + const dex::MethodDeclData generate_layout_params_; + const dex::MethodDeclData add_view_; + + // used for keeping track of which registers are in use + size_t top_register_{0}; + std::vector<dex::Value> register_stack_; + + // Keep track of the views currently in progress. + struct ViewEntry { + dex::Value view; + std::optional<dex::Value> layout_params; + }; + std::vector<ViewEntry> view_stack_; +}; + +} // namespace startop + +#endif // DEX_LAYOUT_COMPILER_H_ diff --git a/startop/view_compiler/java_lang_builder.cc b/startop/view_compiler/java_lang_builder.cc index 0b8754fc7096..920caeecf58e 100644 --- a/startop/view_compiler/java_lang_builder.cc +++ b/startop/view_compiler/java_lang_builder.cc @@ -67,7 +67,7 @@ void JavaLangViewBuilder::Finish() const { "}\n"; // end CompiledView } -void JavaLangViewBuilder::StartView(const string& class_name) { +void JavaLangViewBuilder::StartView(const string& class_name, bool /*is_viewgroup*/) { const string view_var = MakeVar("view"); const string layout_var = MakeVar("layout"); std::string parent = "null"; diff --git a/startop/view_compiler/java_lang_builder.h b/startop/view_compiler/java_lang_builder.h index c8d20b23cd13..69356d3a6594 100644 --- a/startop/view_compiler/java_lang_builder.h +++ b/startop/view_compiler/java_lang_builder.h @@ -35,7 +35,7 @@ class JavaLangViewBuilder { void Finish() const; // Begin creating a view (i.e. process the opening tag) - void StartView(const std::string& class_name); + void StartView(const std::string& class_name, bool is_viewgroup); // Finish a view, after all of its child nodes have been processed. void FinishView(); diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc index 609bcf377b46..ae00187e1908 100644 --- a/startop/view_compiler/main.cc +++ b/startop/view_compiler/main.cc @@ -16,8 +16,11 @@ #include "gflags/gflags.h" +#include "android-base/stringprintf.h" #include "dex_builder.h" +#include "dex_layout_compiler.h" #include "java_lang_builder.h" +#include "layout_validation.h" #include "tinyxml_layout_parser.h" #include "util.h" @@ -32,6 +35,12 @@ namespace { using namespace tinyxml2; +using android::base::StringPrintf; +using startop::dex::ClassBuilder; +using startop::dex::DexBuilder; +using startop::dex::MethodBuilder; +using startop::dex::Prototype; +using startop::dex::TypeDescriptor; using namespace startop::util; using std::string; @@ -41,34 +50,44 @@ DEFINE_bool(dex, false, "Generate a DEX file instead of Java"); DEFINE_string(out, kStdoutFilename, "Where to write the generated class"); DEFINE_string(package, "", "The package name for the generated class (required)"); -class ViewCompilerXmlVisitor : public XMLVisitor { +template <typename Visitor> +class XmlVisitorAdapter : public XMLVisitor { public: - explicit ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {} + explicit XmlVisitorAdapter(Visitor* visitor) : visitor_{visitor} {} bool VisitEnter(const XMLDocument& /*doc*/) override { - builder_->Start(); + visitor_->VisitStartDocument(); return true; } bool VisitExit(const XMLDocument& /*doc*/) override { - builder_->Finish(); + visitor_->VisitEndDocument(); return true; } bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override { - builder_->StartView(element.Name()); + visitor_->VisitStartTag( + std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes( + element.Name())); return true; } bool VisitExit(const XMLElement& /*element*/) override { - builder_->FinishView(); + visitor_->VisitEndTag(); return true; } private: - JavaLangViewBuilder* builder_; + Visitor* visitor_; }; +template <typename Builder> +void CompileLayout(XMLDocument* xml, Builder* builder) { + startop::LayoutCompilerVisitor visitor{builder}; + XmlVisitorAdapter<decltype(visitor)> adapter{&visitor}; + xml->Accept(&adapter); +} + } // end namespace int main(int argc, char** argv) { @@ -88,16 +107,8 @@ int main(int argc, char** argv) { return 1; } - if (FLAGS_dex) { - startop::dex::WriteTestDexFile("test.dex"); - return 0; - } - const char* const filename = argv[kFileNameParam]; - const string layout_name = FindLayoutNameFromFilename(filename); - - // We want to generate Java language code to inflate exactly this layout. This means - // generating code to walk the resource XML too. + const string layout_name = startop::util::FindLayoutNameFromFilename(filename); XMLDocument xml; xml.LoadFile(filename); @@ -108,15 +119,34 @@ int main(int argc, char** argv) { return 1; } + const bool is_stdout = FLAGS_out == kStdoutFilename; + std::ofstream outfile; - if (FLAGS_out != kStdoutFilename) { + if (!is_stdout) { outfile.open(FLAGS_out); } - JavaLangViewBuilder builder{ - FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile}; - - ViewCompilerXmlVisitor visitor{&builder}; - xml.Accept(&visitor); + if (FLAGS_dex) { + DexBuilder dex_file; + string class_name = StringPrintf("%s.CompiledView", FLAGS_package.c_str()); + ClassBuilder compiled_view{dex_file.MakeClass(class_name)}; + MethodBuilder method{compiled_view.CreateMethod( + layout_name, + Prototype{TypeDescriptor::FromClassname("android.view.View"), + TypeDescriptor::FromClassname("android.content.Context"), + TypeDescriptor::Int()})}; + startop::DexViewBuilder builder{&method}; + CompileLayout(&xml, &builder); + method.Encode(); + + slicer::MemView image{dex_file.CreateImage()}; + + (is_stdout ? std::cout : outfile).write(image.ptr<const char>(), image.size()); + } else { + // Generate Java language output. + JavaLangViewBuilder builder{FLAGS_package, layout_name, is_stdout ? std::cout : outfile}; + + CompileLayout(&xml, &builder); + } return 0; } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index a9a128bf6681..312b31899ad6 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2231,7 +2231,7 @@ public class CarrierConfigManager { * e.g.) To use RSCP by default, set the value to "rscp". The signal strength level will * then be determined by #KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY * <p> - * Currently this only supports the value "rscp" + * Currently this supports the value "rscp" and "rssi". * @hide */ // FIXME: this key and related keys must not be exposed without a consistent philosophy for @@ -2875,7 +2875,7 @@ public class CarrierConfigManager { -95, /* SIGNAL_STRENGTH_GOOD */ -85 /* SIGNAL_STRENGTH_GREAT */ }); - sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, ""); + sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "rssi"); sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false); sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false); sDefaults.putBoolean(KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL, false); diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java index f2c14a147230..e6182eda852a 100644 --- a/telephony/java/android/telephony/CellSignalStrength.java +++ b/telephony/java/android/telephony/CellSignalStrength.java @@ -42,6 +42,9 @@ public abstract class CellSignalStrength { public static final int NUM_SIGNAL_STRENGTH_BINS = 5; /** @hide */ + protected static final int NUM_SIGNAL_STRENGTH_THRESHOLDS = NUM_SIGNAL_STRENGTH_BINS - 1; + + /** @hide */ public static final String[] SIGNAL_STRENGTH_NAMES = { "none", "poor", "moderate", "good", "great" }; diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java index 88f6fbc4464d..0760407171ae 100644 --- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -21,6 +21,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; import android.telephony.Rlog; +import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -41,8 +42,18 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements private static final int WCDMA_RSSI_POOR = -107; private static final int WCDMA_RSSI_MIN = -113; - private static final int WCDMA_RSCP_MIN = -120; + private static final int[] sRssiThresholds = new int[]{ + WCDMA_RSSI_POOR, WCDMA_RSSI_MODERATE, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT}; + private static final int WCDMA_RSCP_MAX = -24; + private static final int WCDMA_RSCP_GREAT = -85; + private static final int WCDMA_RSCP_GOOD = -95; + private static final int WCDMA_RSCP_MODERATE = -105; + private static final int WCDMA_RSCP_POOR = -115; + private static final int WCDMA_RSCP_MIN = -120; + + private static final int[] sRscpThresholds = new int[] { + WCDMA_RSCP_POOR, WCDMA_RSCP_MODERATE, WCDMA_RSCP_GOOD, WCDMA_RSCP_GREAT}; // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow. /** @hide */ @@ -54,6 +65,9 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @hide */ public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp"; + // Default to RSSI for backwards compatibility with older devices + private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI; + private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or // CellInfo.UNAVAILABLE if unknown @@ -121,10 +135,6 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } - private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI; - private static final int[] sThresholds = new int[]{ - WCDMA_RSSI_POOR, WCDMA_RSSI_GOOD, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT}; - /** * Retrieve an abstract level value for the overall signal strength. * @@ -140,41 +150,46 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements @Override public void updateLevel(PersistableBundle cc, ServiceState ss) { String calcMethod; - int[] thresholds; + int[] rscpThresholds; if (cc == null) { calcMethod = sLevelCalculationMethod; - thresholds = sThresholds; + rscpThresholds = sRscpThresholds; } else { // TODO: abstract this entire thing into a series of functions calcMethod = cc.getString( CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, sLevelCalculationMethod); - thresholds = cc.getIntArray( + if (TextUtils.isEmpty(calcMethod)) calcMethod = sLevelCalculationMethod; + rscpThresholds = cc.getIntArray( CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY); - if (thresholds == null) thresholds = sThresholds; + if (rscpThresholds == null || rscpThresholds.length != NUM_SIGNAL_STRENGTH_THRESHOLDS) { + rscpThresholds = sRscpThresholds; + } } - int level = thresholds.length; + int level = NUM_SIGNAL_STRENGTH_THRESHOLDS; switch (calcMethod) { case LEVEL_CALCULATION_METHOD_RSCP: if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) { mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; return; } - while (level > 0 && mRscp < thresholds[level - 1]) level--; + while (level > 0 && mRscp < rscpThresholds[level - 1]) level--; mLevel = level; return; + default: + loge("Invalid Level Calculation Method for CellSignalStrengthWcdma = " + + calcMethod); + /** fall through */ case LEVEL_CALCULATION_METHOD_RSSI: if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) { mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; return; } - while (level > 0 && mRssi < thresholds[level - 1]) level--; + while (level > 0 && mRssi < sRssiThresholds[level - 1]) level--; mLevel = level; return; - default: - mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } } @@ -204,7 +219,7 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements } /** - * Get the signal strength as dBm + * Get the RSSI as dBm * * @hide */ @@ -214,12 +229,32 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** * Get the RSCP as dBm + * * @hide */ public int getRscp() { return mRscp; } + /** + * Get the Ec/No as dB + * + * @hide + */ + public int getEcNo() { + return mEcNo; + } + + /** + * Return the Bit Error Rate + * + * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE. + * @hide + */ + public int getBitErrorRate() { + return mBitErrorRate; + } + @Override public int hashCode() { return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel); @@ -304,9 +339,16 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements }; /** - * log + * log warning */ private static void log(String s) { Rlog.w(LOG_TAG, s); } + + /** + * log error + */ + private static void loge(String s) { + Rlog.e(LOG_TAG, s); + } } diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index b258f52d58ec..83738997a067 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -17,10 +17,11 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; +import android.net.LinkProperties; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager; -import android.net.LinkProperties; + +import java.util.Objects; /** * Contains precise data connection state. @@ -32,7 +33,6 @@ import android.net.LinkProperties; * <li>Network type of the connection. * <li>APN type. * <li>APN. - * <li>Data connection change reason. * <li>The properties of the network link. * <li>Data connection fail cause. * </ul> @@ -45,7 +45,6 @@ public class PreciseDataConnectionState implements Parcelable { private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; private String mAPNType = ""; private String mAPN = ""; - private String mReason = ""; private LinkProperties mLinkProperties = null; private String mFailCause = ""; @@ -55,14 +54,12 @@ public class PreciseDataConnectionState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseDataConnectionState(int state, int networkType, - String apnType, String apn, String reason, - LinkProperties linkProperties, String failCause) { + public PreciseDataConnectionState(int state, int networkType, String apnType, String apn, + LinkProperties linkProperties, String failCause) { mState = state; mNetworkType = networkType; mAPNType = apnType; mAPN = apn; - mReason = reason; mLinkProperties = linkProperties; mFailCause = failCause; } @@ -83,7 +80,6 @@ public class PreciseDataConnectionState implements Parcelable { mNetworkType = in.readInt(); mAPNType = in.readString(); mAPN = in.readString(); - mReason = in.readString(); mLinkProperties = (LinkProperties)in.readParcelable(null); mFailCause = in.readString(); } @@ -144,14 +140,6 @@ public class PreciseDataConnectionState implements Parcelable { } /** - * Get data connection change reason. - */ - @UnsupportedAppUsage - public String getDataConnectionChangeReason() { - return mReason; - } - - /** * Get the properties of the network link. */ @UnsupportedAppUsage @@ -178,7 +166,6 @@ public class PreciseDataConnectionState implements Parcelable { out.writeInt(mNetworkType); out.writeString(mAPNType); out.writeString(mAPN); - out.writeString(mReason); out.writeParcelable(mLinkProperties, flags); out.writeString(mFailCause); } @@ -197,16 +184,7 @@ public class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + mState; - result = prime * result + mNetworkType; - result = prime * result + ((mAPNType == null) ? 0 : mAPNType.hashCode()); - result = prime * result + ((mAPN == null) ? 0 : mAPN.hashCode()); - result = prime * result + ((mReason == null) ? 0 : mReason.hashCode()); - result = prime * result + ((mLinkProperties == null) ? 0 : mLinkProperties.hashCode()); - result = prime * result + ((mFailCause == null) ? 0 : mFailCause.hashCode()); - return result; + return Objects.hash(mState, mNetworkType, mAPNType, mAPN, mLinkProperties, mFailCause); } @Override @@ -252,13 +230,6 @@ public class PreciseDataConnectionState implements Parcelable { if (mNetworkType != other.mNetworkType) { return false; } - if (mReason == null) { - if (other.mReason != null) { - return false; - } - } else if (!mReason.equals(other.mReason)) { - return false; - } if (mState != other.mState) { return false; } @@ -273,7 +244,6 @@ public class PreciseDataConnectionState implements Parcelable { sb.append(", Network type: " + mNetworkType); sb.append(", APN type: " + mAPNType); sb.append(", APN: " + mAPN); - sb.append(", Change reason: " + mReason); sb.append(", Link properties: " + mLinkProperties); sb.append(", Fail cause: " + mFailCause); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4598afaa41ce..8dfdb2f4a334 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -772,7 +772,6 @@ public class TelephonyManager { * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type. * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type. * The {@link #EXTRA_DATA_APN} extra indicates the APN. - * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason. * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface. * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause. * @@ -783,7 +782,6 @@ public class TelephonyManager { * @see #EXTRA_DATA_NETWORK_TYPE * @see #EXTRA_DATA_APN_TYPE * @see #EXTRA_DATA_APN - * @see #EXTRA_DATA_CHANGE_REASON * @see #EXTRA_DATA_IFACE * @see #EXTRA_DATA_FAILURE_CAUSE * @hide @@ -873,18 +871,6 @@ public class TelephonyManager { /** * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast - * for an String representation of the change reason. - * - * <p class="note"> - * Retrieve with - * {@link android.content.Intent#getStringExtra(String name)}. - * - * @hide - */ - public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_KEY; - - /** - * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast * for an String representation of the data interface. * * <p class="note"> diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java index 5122c7daafe6..709b3aa0f804 100644 --- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java +++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java @@ -23,6 +23,10 @@ import android.os.Parcel; * @hide - TODO(sahinc) make this public */ public class Rcs1To1Thread extends RcsThread { + public Rcs1To1Thread(int threadId) { + super(threadId); + } + public static final Creator<Rcs1To1Thread> CREATOR = new Creator<Rcs1To1Thread>() { @Override public Rcs1To1Thread createFromParcel(Parcel in) { @@ -36,6 +40,7 @@ public class Rcs1To1Thread extends RcsThread { }; protected Rcs1To1Thread(Parcel in) { + super(in); } @Override @@ -45,5 +50,7 @@ public class Rcs1To1Thread extends RcsThread { @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(RCS_1_TO_1_TYPE); + super.writeToParcel(dest, flags); } } diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java index 150c4d49757c..d954b2d70ac3 100644 --- a/telephony/java/android/telephony/ims/RcsGroupThread.java +++ b/telephony/java/android/telephony/ims/RcsGroupThread.java @@ -36,6 +36,7 @@ public class RcsGroupThread extends RcsThread { }; protected RcsGroupThread(Parcel in) { + super(in); } @Override @@ -45,5 +46,7 @@ public class RcsGroupThread extends RcsThread { @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(RCS_GROUP_TYPE); + super.writeToParcel(dest, flags); } } diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java index 4198c78a8191..1bf6ffd81ca0 100644 --- a/telephony/java/android/telephony/ims/RcsMessageStore.java +++ b/telephony/java/android/telephony/ims/RcsMessageStore.java @@ -16,6 +16,8 @@ package android.telephony.ims; +import android.annotation.Nullable; +import android.annotation.WorkerThread; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Rlog; @@ -27,26 +29,93 @@ import android.telephony.ims.aidl.IRcs; * @hide - TODO make this public */ public class RcsMessageStore { - private static final String TAG = "RcsMessageStore"; - private static final boolean VDBG = false; + static final String TAG = "RcsMessageStore"; /** - * Delete the RcsThread identified by the given threadId. + * Returns the first chunk of existing {@link RcsThread}s in the common storage. + * @param queryParameters Parameters to specify to return a subset of all RcsThreads. + * Passing a value of null will return all threads. + */ + @WorkerThread + public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParameters queryParameters) { + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + return iRcs.getRcsThreads(queryParameters); + } + } catch (RemoteException re) { + Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re); + } + + return null; + } + + /** + * Returns the next chunk of {@link RcsThread}s in the common storage. + * @param continuationToken A token to continue the query to get the next chunk. This is + * obtained through {@link RcsThreadQueryResult#nextChunkToken}. + */ + @WorkerThread + public RcsThreadQueryResult getRcsThreads(RcsThreadQueryContinuationToken continuationToken) { + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + return iRcs.getRcsThreadsWithToken(continuationToken); + } + } catch (RemoteException re) { + Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re); + } + + return null; + } + + /** + * Creates a new 1 to 1 thread with the given participant and persists it in the storage. + */ + @WorkerThread + public Rcs1To1Thread createRcs1To1Thread(RcsParticipant recipient) { + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + return iRcs.createRcs1To1Thread(recipient); + } + } catch (RemoteException re) { + Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcs1To1Thread", re); + } + + return null; + } + + /** + * Delete the {@link RcsThread} identified by the given threadId. * @param threadId threadId of the thread to be deleted. */ + @WorkerThread public void deleteThread(int threadId) { - if (VDBG) logd("deleteThread: threadId: " + threadId); try { IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); if (iRcs != null) { iRcs.deleteThread(threadId); } } catch (RemoteException re) { - + Rlog.e(TAG, "RcsMessageStore: Exception happened during deleteThread", re); } } - private static void logd(String msg) { - Rlog.d(TAG, msg); + /** + * Creates a new participant and persists it in the storage. + * @param canonicalAddress The defining address (e.g. phone number) of the participant. + */ + public RcsParticipant createRcsParticipant(String canonicalAddress) { + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + return iRcs.createRcsParticipant(canonicalAddress); + } + } catch (RemoteException re) { + Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcsParticipant", re); + } + + return null; } } diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java index 318dba3fcbca..70500aaa2e8b 100644 --- a/telephony/java/android/telephony/ims/RcsParticipant.java +++ b/telephony/java/android/telephony/ims/RcsParticipant.java @@ -23,6 +23,16 @@ import android.os.Parcelable; * @hide - TODO(sahinc) make this public */ public class RcsParticipant implements Parcelable { + /** + * Returns the row id of this participant. + * + * TODO(sahinc) implement + * @hide + */ + public int getId() { + return 12345; + } + public static final Creator<RcsParticipant> CREATOR = new Creator<RcsParticipant>() { @Override public RcsParticipant createFromParcel(Parcel in) { diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java index 2969ffdda0e8..c0a0d946d204 100644 --- a/telephony/java/android/telephony/ims/RcsThread.java +++ b/telephony/java/android/telephony/ims/RcsThread.java @@ -16,7 +16,9 @@ package android.telephony.ims; +import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; /** * RcsThread represents a single RCS conversation thread. It holds messages that were sent and @@ -24,5 +26,50 @@ import android.os.Parcelable; * @hide - TODO(sahinc) make this public */ public abstract class RcsThread implements Parcelable { + // Since this is an abstract class that gets parcelled, the sub-classes need to write these + // magic values into the parcel so that we know which type to unparcel into. + protected static final int RCS_1_TO_1_TYPE = 998; + protected static final int RCS_GROUP_TYPE = 999; + protected int mThreadId; + + protected RcsThread(int threadId) { + mThreadId = threadId; + } + + protected RcsThread(Parcel in) { + mThreadId = in.readInt(); + } + + public static final Creator<RcsThread> CREATOR = new Creator<RcsThread>() { + @Override + public RcsThread createFromParcel(Parcel in) { + int type = in.readInt(); + + switch (type) { + case RCS_1_TO_1_TYPE: + return new Rcs1To1Thread(in); + case RCS_GROUP_TYPE: + return new RcsGroupThread(in); + default: + Log.e(RcsMessageStore.TAG, "Cannot unparcel RcsThread, wrong type: " + type); + } + return null; + } + + @Override + public RcsThread[] newArray(int size) { + return new RcsThread[0]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mThreadId); + } } diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl new file mode 100644 index 000000000000..7bcebfa08fcb --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony.ims; + +parcelable RcsThreadQueryContinuationToken; diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java new file mode 100644 index 000000000000..931e93dc8bf1 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A continuation token to provide for {@link RcsMessageStore#getRcsThreads}. Use this token to + * break large queries into manageable chunks + * @hide - TODO make this public + */ +public class RcsThreadQueryContinuationToken implements Parcelable { + protected RcsThreadQueryContinuationToken(Parcel in) { + } + + public static final Creator<RcsThreadQueryContinuationToken> CREATOR = + new Creator<RcsThreadQueryContinuationToken>() { + @Override + public RcsThreadQueryContinuationToken createFromParcel(Parcel in) { + return new RcsThreadQueryContinuationToken(in); + } + + @Override + public RcsThreadQueryContinuationToken[] newArray(int size) { + return new RcsThreadQueryContinuationToken[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + } +} diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl new file mode 100644 index 000000000000..feb2d4dec094 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony.ims; + +parcelable RcsThreadQueryParameters; diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java new file mode 100644 index 000000000000..f2c4ab1884ca --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +import android.annotation.CheckResult; +import android.os.Parcel; +import android.os.Parcelable; + +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +/** + * The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} in + * order to select a subset of {@link RcsThread}s present in the message store. + * @hide TODO - make the Builder and builder() public. The rest should stay internal only. + */ +public class RcsThreadQueryParameters implements Parcelable { + private final boolean mIsGroup; + private final Set<RcsParticipant> mRcsParticipants; + private final int mLimit; + private final boolean mIsAscending; + + RcsThreadQueryParameters(boolean isGroup, Set<RcsParticipant> participants, int limit, + boolean isAscending) { + mIsGroup = isGroup; + mRcsParticipants = participants; + mLimit = limit; + mIsAscending = isAscending; + } + + /** + * Returns a new builder to build a query with. + * TODO - make public + */ + public static Builder builder() { + return new Builder(); + } + + /** + * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get + * the list of participants. + * @hide + */ + public Set<RcsParticipant> getRcsParticipants() { + return mRcsParticipants; + } + + /** + * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get + * whether group threads should be queried + * @hide + */ + public boolean isGroupThread() { + return mIsGroup; + } + + /** + * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get + * the number of tuples the result query should be limited to. + */ + public int getLimit() { + return mLimit; + } + + /** + * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to + * determine the sort order. + */ + public boolean isAscending() { + return mIsAscending; + } + + /** + * A helper class to build the {@link RcsThreadQueryParameters}. + */ + public static class Builder { + private boolean mIsGroupThread; + private Set<RcsParticipant> mParticipants; + private int mLimit = 100; + private boolean mIsAscending; + + /** + * Package private constructor for {@link RcsThreadQueryParameters.Builder}. To obtain this, + * {@link RcsThreadQueryParameters#builder()} needs to be called. + */ + Builder() { + mParticipants = new HashSet<>(); + } + + /** + * Limits the query to only return group threads. + * @param isGroupThread Whether to limit the query result to group threads. + * @return The same instance of the builder to chain parameters. + */ + @CheckResult + public Builder isGroupThread(boolean isGroupThread) { + mIsGroupThread = isGroupThread; + return this; + } + + /** + * Limits the query to only return threads that contain the given participant. + * @param participant The participant that must be included in all of the returned threads. + * @return The same instance of the builder to chain parameters. + */ + @CheckResult + public Builder withParticipant(RcsParticipant participant) { + mParticipants.add(participant); + return this; + } + + /** + * Limits the query to only return threads that contain the given list of participants. + * @param participants An iterable list of participants that must be included in all of the + * returned threads. + * @return The same instance of the builder to chain parameters. + */ + @CheckResult + public Builder withParticipants(Iterable<RcsParticipant> participants) { + for (RcsParticipant participant : participants) { + mParticipants.add(participant); + } + return this; + } + + /** + * Desired number of threads to be returned from the query. Passing in 0 will return all + * existing threads at once. The limit defaults to 100. + * @param limit The number to limit the query result to. + * @return The same instance of the builder to chain parameters. + * @throws InvalidParameterException If the given limit is negative. + */ + @CheckResult + public Builder limitResultsTo(int limit) throws InvalidParameterException { + if (limit < 0) { + throw new InvalidParameterException("The query limit must be non-negative"); + } + + mLimit = limit; + return this; + } + + /** + * Sorts the results returned from the query via thread IDs. + * + * TODO - add sorting support for other fields + * + * @param isAscending whether to sort in ascending order or not + * @return The same instance of the builder to chain parameters. + */ + @CheckResult + public Builder sort(boolean isAscending) { + mIsAscending = isAscending; + return this; + } + + /** + * Builds the {@link RcsThreadQueryParameters} to use in + * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} + * + * @return An instance of {@link RcsThreadQueryParameters} to use with the thread query. + */ + public RcsThreadQueryParameters build() { + return new RcsThreadQueryParameters( + mIsGroupThread, mParticipants, mLimit, mIsAscending); + } + } + + /** + * Parcelable boilerplate below. + */ + protected RcsThreadQueryParameters(Parcel in) { + mIsGroup = in.readBoolean(); + + ArrayList<RcsParticipant> participantArrayList = new ArrayList<>(); + in.readTypedList(participantArrayList, RcsParticipant.CREATOR); + mRcsParticipants = new HashSet<>(participantArrayList); + + mLimit = in.readInt(); + mIsAscending = in.readBoolean(); + } + + public static final Creator<RcsThreadQueryParameters> CREATOR = + new Creator<RcsThreadQueryParameters>() { + @Override + public RcsThreadQueryParameters createFromParcel(Parcel in) { + return new RcsThreadQueryParameters(in); + } + + @Override + public RcsThreadQueryParameters[] newArray(int size) { + return new RcsThreadQueryParameters[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeBoolean(mIsGroup); + dest.writeTypedList(new ArrayList<>(mRcsParticipants)); + dest.writeInt(mLimit); + dest.writeBoolean(mIsAscending); + } + +} diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl new file mode 100644 index 000000000000..4b06529d1294 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony.ims; + +parcelable RcsThreadQueryResult; diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java new file mode 100644 index 000000000000..47715f8410d6 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.ims; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken, + * RcsThreadQueryParameters)} + * call. This class allows getting the token for querying the next batch of threads in order to + * prevent handling large amounts of data at once. + * + * @hide + */ +public class RcsThreadQueryResult implements Parcelable { + private RcsThreadQueryContinuationToken mContinuationToken; + private List<RcsThread> mRcsThreads; + + /** + * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController} + * to create query results + * + * @hide + */ + public RcsThreadQueryResult( + RcsThreadQueryContinuationToken continuationToken, List<RcsThread> rcsThreads) { + mContinuationToken = continuationToken; + mRcsThreads = rcsThreads; + } + + /** + * Returns a token to call + * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)} + * to get the next batch of {@link RcsThread}s. + */ + public RcsThreadQueryContinuationToken nextChunkToken() { + return mContinuationToken; + } + + /** + * Returns all the RcsThreads in the current query result. Call {@link + * RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)} to get the next batch of + * {@link RcsThread}s. + */ + public List<RcsThread> getThreads() { + return mRcsThreads; + } + + protected RcsThreadQueryResult(Parcel in) { + // TODO - implement + } + + public static final Creator<RcsThreadQueryResult> CREATOR = + new Creator<RcsThreadQueryResult>() { + @Override + public RcsThreadQueryResult createFromParcel(Parcel in) { + return new RcsThreadQueryResult(in); + } + + @Override + public RcsThreadQueryResult[] newArray(int size) { + return new RcsThreadQueryResult[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + // TODO - implement + } +} diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl index b2e2fadca138..9badac5be230 100644 --- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl +++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl @@ -16,14 +16,29 @@ package android.telephony.ims.aidl; +import android.telephony.ims.RcsParticipant; +import android.telephony.ims.Rcs1To1Thread; +import android.telephony.ims.RcsThreadQueryContinuationToken; +import android.telephony.ims.RcsThreadQueryParameters; +import android.telephony.ims.RcsThreadQueryResult; + /** * RPC definition between RCS storage APIs and phone process. * {@hide} */ interface IRcs { // RcsMessageStore APIs + RcsThreadQueryResult getRcsThreads(in RcsThreadQueryParameters queryParameters); + + RcsThreadQueryResult getRcsThreadsWithToken( + in RcsThreadQueryContinuationToken continuationToken); + void deleteThread(int threadId); + Rcs1To1Thread createRcs1To1Thread(in RcsParticipant participant); + + RcsParticipant createRcsParticipant(String canonicalAddress); + // RcsThread APIs int getMessageCount(int rcsThreadId); }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index d9f5c3f6d0fa..02a6f311c1da 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -50,13 +50,13 @@ interface ITelephonyRegistry { void notifyDataActivity(int state); void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, in LinkProperties linkProperties, + String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, in LinkProperties linkProperties, + String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionFailed(String reason, String apnType); - void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType); + void notifyDataConnectionFailed(String apnType); + void notifyDataConnectionFailedForSubscriber(int subId, String apnType); void notifyCellLocation(in Bundle cellLocation); void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); @@ -67,7 +67,7 @@ interface ITelephonyRegistry { void notifyPreciseCallState(int ringingCallState, int foregroundCallState, int backgroundCallState); void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, + void notifyPreciseDataConnectionFailed(String apnType, String apn, String failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); void notifySrvccStateChanged(in int subId, in int lteState); diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 21f3b92c6c4f..e87d28c6f9e9 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -79,8 +79,6 @@ public class PhoneConstants { public static final int SIM_ACTIVATION_TYPE_DATA = 1; public static final String PHONE_NAME_KEY = "phoneName"; - public static final String FAILURE_REASON_KEY = "reason"; - public static final String STATE_CHANGE_REASON_KEY = "reason"; public static final String DATA_NETWORK_TYPE_KEY = "networkType"; public static final String DATA_FAILURE_CAUSE_KEY = "failCause"; public static final String DATA_APN_TYPE_KEY = "apnType"; diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index 0ac35bc2628c..e9a5ff70a7cc 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -119,7 +119,7 @@ public class MockContentProvider extends ContentProvider { @Override public IBinder asBinder() { - throw new UnsupportedOperationException(); + return MockContentProvider.this.getIContentProviderBinder(); } @Override @@ -279,6 +279,13 @@ public class MockContentProvider extends ContentProvider { } /** + * @hide + */ + public IBinder getIContentProviderBinder() { + throw new UnsupportedOperationException("unimplemented mock method"); + } + + /** * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use * when directly instantiating the provider for testing. * diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk index adc7cab91389..7b348d73747a 100644 --- a/tests/RcsTests/Android.mk +++ b/tests/RcsTests/Android.mk @@ -11,7 +11,7 @@ LOCAL_PRIVATE_PLATFORM_APIS := true LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base -LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4 +LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4 truth-prebuilt include $(BUILD_PACKAGE) diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java index 290e04ce8abb..44277edcdb8c 100644 --- a/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java +++ b/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.tests.rcs; +package com.android.tests.ims; import android.support.test.runner.AndroidJUnit4; import android.telephony.ims.RcsMessageStore; diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java new file mode 100644 index 000000000000..a890a389bdfc --- /dev/null +++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 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.tests.ims; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Bundle; +import android.support.test.runner.AndroidJUnit4; +import android.telephony.ims.RcsParticipant; +import android.telephony.ims.RcsThreadQueryParameters; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +@RunWith(AndroidJUnit4.class) +public class RcsThreadQueryParametersTest { + private RcsThreadQueryParameters mRcsThreadQueryParameters; + @Mock RcsParticipant mMockParticipant; + + @Test + public void testUnparceling() { + String key = "some key"; + mRcsThreadQueryParameters = RcsThreadQueryParameters.builder() + .isGroupThread(true) + .withParticipant(mMockParticipant) + .limitResultsTo(50) + .sort(true) + .build(); + + Bundle bundle = new Bundle(); + bundle.putParcelable(key, mRcsThreadQueryParameters); + mRcsThreadQueryParameters = bundle.getParcelable(key); + + assertThat(mRcsThreadQueryParameters.isGroupThread()).isTrue(); + assertThat(mRcsThreadQueryParameters.getRcsParticipants()).contains(mMockParticipant); + assertThat(mRcsThreadQueryParameters.getLimit()).isEqualTo(50); + assertThat(mRcsThreadQueryParameters.isAscending()).isTrue(); + } +} diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING new file mode 100644 index 000000000000..c1d95ac85c23 --- /dev/null +++ b/tests/RollbackTest/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "RollbackTest" + } + ] +} diff --git a/tests/WindowManagerStressTest/src/test/windowmanagerstresstest/MainActivity.java b/tests/WindowManagerStressTest/src/test/windowmanagerstresstest/MainActivity.java index d5987a5373b4..85646987940f 100644 --- a/tests/WindowManagerStressTest/src/test/windowmanagerstresstest/MainActivity.java +++ b/tests/WindowManagerStressTest/src/test/windowmanagerstresstest/MainActivity.java @@ -28,6 +28,7 @@ import android.view.DisplayCutout; import android.view.IWindowSession; import android.view.InsetsState; import android.view.Surface; +import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; @@ -106,7 +107,7 @@ public class MainActivity extends Activity { window.mSeq, mLayoutParams, -1, -1, View.VISIBLE, 0, -1, mTmpRect, mTmpRect, mTmpRect, mTmpRect, mTmpRect, mTmpRect, mTmpRect, new DisplayCutout.ParcelableWrapper(), new MergedConfiguration(), - new Surface(), new InsetsState()); + new SurfaceControl(), new InsetsState()); } catch (RemoteException e) { e.printStackTrace(); } diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py index 6476abd8268e..acf1f1e9902e 100644 --- a/tools/apilint/apilint.py +++ b/tools/apilint/apilint.py @@ -26,7 +26,7 @@ $ git blame api/current.txt -t -e > /tmp/currentblame.txt $ apilint.py /tmp/currentblame.txt previous.txt --no-color """ -import re, sys, collections, traceback, argparse +import re, sys, collections, traceback, argparse, itertools BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) @@ -50,45 +50,37 @@ def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False): return "\033[%sm" % (";".join(codes)) -def ident(raw): - """Strips superficial signature changes, giving us a strong key that - can be used to identify members across API levels.""" - raw = raw.replace(" deprecated ", " ") - raw = raw.replace(" synchronized ", " ") - raw = raw.replace(" final ", " ") - raw = re.sub("<.+?>", "", raw) - if " throws " in raw: - raw = raw[:raw.index(" throws ")] - return raw - - class Field(): - def __init__(self, clazz, line, raw, blame): + def __init__(self, clazz, line, raw, blame, sig_format = 1): self.clazz = clazz self.line = line self.raw = raw.strip(" {;") self.blame = blame - # drop generics for now; may need multiple passes - raw = re.sub("<[^<]+?>", "", raw) - raw = re.sub("<[^<]+?>", "", raw) + if sig_format == 2: + V2LineParser(raw).parse_into_field(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) - raw = raw.split() - self.split = list(raw) + raw = raw.split() + self.split = list(raw) - for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]: - while r in raw: raw.remove(r) + for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]: + while r in raw: raw.remove(r) - # ignore annotations for now - raw = [ r for r in raw if not r.startswith("@") ] + # ignore annotations for now + raw = [ r for r in raw if not r.startswith("@") ] - self.typ = raw[0] - self.name = raw[1].strip(";") - if len(raw) >= 4 and raw[2] == "=": - self.value = raw[3].strip(';"') - else: - self.value = None - self.ident = ident(self.raw) + self.typ = raw[0] + self.name = raw[1].strip(";") + if len(raw) >= 4 and raw[2] == "=": + self.value = raw[3].strip(';"') + else: + self.value = None + + self.ident = "-".join((self.typ, self.name, self.value or "")) def __hash__(self): return hash(self.raw) @@ -96,48 +88,55 @@ class Field(): def __repr__(self): return self.raw - class Method(): - def __init__(self, clazz, line, raw, blame): + def __init__(self, clazz, line, raw, blame, sig_format = 1): self.clazz = clazz self.line = line self.raw = raw.strip(" {;") self.blame = blame - # drop generics for now; may need multiple passes - raw = re.sub("<[^<]+?>", "", raw) - raw = re.sub("<[^<]+?>", "", raw) - - # handle each clause differently - raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups() - - # parse prefixes - raw = re.split("[\s]+", raw_prefix) - for r in ["", ";"]: - while r in raw: raw.remove(r) - self.split = list(raw) - - for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator"]: - while r in raw: raw.remove(r) - - self.typ = raw[0] - self.name = raw[1] - - # parse args - self.args = [] - for arg in re.split(",\s*", raw_args): - arg = re.split("\s", arg) - # ignore annotations for now - arg = [ a for a in arg if not a.startswith("@") ] - if len(arg[0]) > 0: - self.args.append(arg[0]) + if sig_format == 2: + V2LineParser(raw).parse_into_method(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) + + # handle each clause differently + raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups() + + # parse prefixes + raw = re.split("[\s]+", raw_prefix) + for r in ["", ";"]: + while r in raw: raw.remove(r) + self.split = list(raw) + + for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator", "synchronized"]: + while r in raw: raw.remove(r) + + self.typ = raw[0] + self.name = raw[1] + + # parse args + self.args = [] + for arg in re.split(",\s*", raw_args): + arg = re.split("\s", arg) + # ignore annotations for now + arg = [ a for a in arg if not a.startswith("@") ] + if len(arg[0]) > 0: + self.args.append(arg[0]) + + # parse throws + self.throws = [] + for throw in re.split(",\s*", raw_throws): + self.throws.append(throw) + else: + raise ValueError("Unknown signature format: " + sig_format) - # parse throws - self.throws = [] - for throw in re.split(",\s*", raw_throws): - self.throws.append(throw) + self.ident = "-".join((self.typ, self.name, "-".join(self.args))) - self.ident = ident(self.raw) + def sig_matches(self, typ, name, args): + return typ == self.typ and name == self.name and args == self.args def __hash__(self): return hash(self.raw) @@ -147,7 +146,7 @@ class Method(): class Class(): - def __init__(self, pkg, line, raw, blame): + def __init__(self, pkg, line, raw, blame, sig_format = 1): self.pkg = pkg self.line = line self.raw = raw.strip(" {;") @@ -156,31 +155,44 @@ class Class(): self.fields = [] self.methods = [] - # drop generics for now; may need multiple passes - raw = re.sub("<[^<]+?>", "", raw) - raw = re.sub("<[^<]+?>", "", raw) + if sig_format == 2: + V2LineParser(raw).parse_into_class(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) + + raw = raw.split() + self.split = list(raw) + if "class" in raw: + self.fullname = raw[raw.index("class")+1] + elif "interface" in raw: + self.fullname = raw[raw.index("interface")+1] + elif "@interface" in raw: + self.fullname = raw[raw.index("@interface")+1] + else: + raise ValueError("Funky class type %s" % (self.raw)) - raw = raw.split() - self.split = list(raw) - if "class" in raw: - self.fullname = raw[raw.index("class")+1] - elif "interface" in raw: - self.fullname = raw[raw.index("interface")+1] - elif "@interface" in raw: - self.fullname = raw[raw.index("@interface")+1] - else: - raise ValueError("Funky class type %s" % (self.raw)) + if "extends" in raw: + self.extends = raw[raw.index("extends")+1] + else: + self.extends = None - if "extends" in raw: - self.extends = raw[raw.index("extends")+1] - self.extends_path = self.extends.split(".") + if "implements" in raw: + self.implements = raw[raw.index("implements")+1] + else: + self.implements = None else: - self.extends = None - self.extends_path = [] + raise ValueError("Unknown signature format: " + sig_format) self.fullname = self.pkg.name + "." + self.fullname self.fullname_path = self.fullname.split(".") + if self.extends is not None: + self.extends_path = self.extends.split(".") + else: + self.extends_path = [] + self.name = self.fullname[self.fullname.rindex(".")+1:] def merge_from(self, other): @@ -208,6 +220,318 @@ class Package(): def __repr__(self): return self.raw +class V2Tokenizer(object): + __slots__ = ["raw"] + + DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.') + STRING_SPECIAL = re.compile(r'["\\]') + + def __init__(self, raw): + self.raw = raw + + def tokenize(self): + tokens = [] + current = 0 + raw = self.raw + length = len(raw) + + while current < length: + while current < length: + start = current + match = V2Tokenizer.DELIMITER.search(raw, start) + if match is not None: + match_start = match.start() + if match_start == current: + end = match.end() + else: + end = match_start + else: + end = length + + token = raw[start:end] + current = end + + if token == "" or token[0] == " ": + continue + else: + break + + if token == "@": + if raw[start:start+11] == "@interface ": + current = start + 11 + tokens.append("@interface") + continue + elif token == '/': + if raw[start:start+2] == "//": + current = length + continue + elif token == '"': + current, string_token = self.tokenize_string(raw, length, current) + tokens.append(token + string_token) + continue + + tokens.append(token) + + return tokens + + def tokenize_string(self, raw, length, current): + start = current + end = length + while start < end: + match = V2Tokenizer.STRING_SPECIAL.search(raw, start) + if match: + if match.group() == '"': + end = match.end() + break + elif match.group() == '\\': + # ignore whatever is after the slash + start += 2 + else: + raise ValueError("Unexpected match: `%s`" % (match.group())) + else: + raise ValueError("Unexpected EOF tokenizing string: `%s`" % (raw[current - 1:],)) + + token = raw[current:end] + return end, token + +class V2LineParser(object): + __slots__ = ["tokenized", "current", "len"] + + MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized".split()) + JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split()) + + def __init__(self, raw): + self.tokenized = V2Tokenizer(raw).tokenize() + self.current = 0 + self.len = len(self.tokenized) + + def parse_into_method(self, method): + method.split = [] + kind = self.parse_one_of("ctor", "method") + method.split.append(kind) + annotations = self.parse_annotations() + method.split.extend(self.parse_modifiers()) + self.parse_matching_paren("<", ">") + if "@Deprecated" in annotations: + method.split.append("deprecated") + if kind == "ctor": + method.typ = "ctor" + else: + method.typ = self.parse_type() + method.split.append(method.typ) + method.name = self.parse_name() + method.split.append(method.name) + self.parse_token("(") + method.args = self.parse_args() + self.parse_token(")") + method.throws = self.parse_throws() + if "@interface" in method.clazz.split: + self.parse_annotation_default() + self.parse_token(";") + self.parse_eof() + + def parse_into_class(self, clazz): + clazz.split = [] + annotations = self.parse_annotations() + if "@Deprecated" in annotations: + clazz.split.append("deprecated") + clazz.split.extend(self.parse_modifiers()) + kind = self.parse_one_of("class", "interface", "@interface", "enum") + if kind == "enum": + # enums are implicitly final + clazz.split.append("final") + clazz.split.append(kind) + clazz.fullname = self.parse_name() + self.parse_matching_paren("<", ">") + extends = self.parse_extends() + clazz.extends = extends[0] if extends else None + implements = self.parse_implements() + clazz.implements = implements[0] if implements else None + # The checks assume that interfaces are always found in implements, which isn't true for + # subinterfaces. + if not implements and "interface" in clazz.split: + clazz.implements = clazz.extends + self.parse_token("{") + self.parse_eof() + + def parse_into_field(self, field): + kind = self.parse_token("field") + field.split = [kind] + annotations = self.parse_annotations() + if "@Deprecated" in annotations: + field.split.append("deprecated") + field.split.extend(self.parse_modifiers()) + field.typ = self.parse_type() + field.split.append(field.typ) + field.name = self.parse_name() + field.split.append(field.name) + if self.parse_if("="): + field.value = self.parse_value_stripped() + else: + field.value = None + + self.parse_token(";") + self.parse_eof() + + def lookahead(self): + return self.tokenized[self.current] + + def parse_one_of(self, *options): + found = self.lookahead() + if found not in options: + raise ValueError("Parsing failed, expected one of `%s` but found `%s` in %s" % (options, found, repr(self.tokenized))) + return self.parse_token() + + def parse_token(self, tok = None): + found = self.lookahead() + if tok is not None and found != tok: + raise ValueError("Parsing failed, expected `%s` but found `%s` in %s" % (tok, found, repr(self.tokenized))) + self.current += 1 + return found + + def eof(self): + return self.current == self.len + + def parse_eof(self): + if not self.eof(): + raise ValueError("Parsing failed, expected EOF, but %s has not been parsed in %s" % (self.tokenized[self.current:], self.tokenized)) + + def parse_if(self, tok): + if not self.eof() and self.lookahead() == tok: + self.parse_token() + return True + return False + + def parse_annotations(self): + ret = [] + while self.lookahead() == "@": + ret.append(self.parse_annotation()) + return ret + + def parse_annotation(self): + ret = self.parse_token("@") + self.parse_token() + self.parse_matching_paren("(", ")") + return ret + + def parse_matching_paren(self, open, close): + start = self.current + if not self.parse_if(open): + return + length = len(self.tokenized) + count = 1 + while count > 0: + if self.current == length: + raise ValueError("Unexpected EOF looking for closing paren: `%s`" % (self.tokenized[start:],)) + t = self.parse_token() + if t == open: + count += 1 + elif t == close: + count -= 1 + return self.tokenized[start:self.current] + + def parse_modifiers(self): + ret = [] + while self.lookahead() in V2LineParser.MODIFIERS: + ret.append(self.parse_token()) + return ret + + def parse_kotlin_nullability(self): + t = self.lookahead() + if t == "?" or t == "!": + return self.parse_token() + return None + + def parse_type(self): + type = self.parse_token() + if type in V2LineParser.JAVA_LANG_TYPES: + type = "java.lang." + type + self.parse_matching_paren("<", ">") + while True: + t = self.lookahead() + if t == "[]": + type += self.parse_token() + elif self.parse_kotlin_nullability() is not None: + pass # discard nullability for now + else: + break + return type + + def parse_arg_type(self): + type = self.parse_type() + if self.parse_if("..."): + type += "..." + self.parse_kotlin_nullability() # discard nullability for now + return type + + def parse_name(self): + return self.parse_token() + + def parse_args(self): + args = [] + if self.lookahead() == ")": + return args + + while True: + args.append(self.parse_arg()) + if self.lookahead() == ")": + return args + self.parse_token(",") + + def parse_arg(self): + self.parse_annotations() + type = self.parse_arg_type() + l = self.lookahead() + if l != "," and l != ")": + self.parse_token() # kotlin argument name + if self.parse_if('='): # kotlin default value + (self.parse_matching_paren('(', ')') or + self.parse_matching_paren('{', '}') or + self.parse_token() and self.parse_matching_paren('(', ')')) + return type + + def parse_throws(self): + ret = [] + if self.parse_if("throws"): + ret.append(self.parse_type()) + while self.parse_if(","): + ret.append(self.parse_type()) + return ret + + def parse_extends(self): + if self.parse_if("extends"): + return self.parse_space_delimited_type_list() + return [] + + def parse_implements(self): + if self.parse_if("implements"): + return self.parse_space_delimited_type_list() + return [] + + def parse_space_delimited_type_list(self, terminals = ["implements", "{"]): + types = [] + while True: + types.append(self.parse_type()) + if self.lookahead() in terminals: + return types + + def parse_annotation_default(self): + if self.parse_if("default"): + self.parse_value() + + def parse_value(self): + if self.lookahead() == "{": + return " ".join(self.parse_matching_paren("{", "}")) + elif self.lookahead() == "(": + return " ".join(self.parse_matching_paren("(", ")")) + else: + return self.parse_token() + + def parse_value_stripped(self): + value = self.parse_value() + if value[0] == '"': + return value[1:-1] + return value + def _parse_stream(f, clazz_cb=None, base_f=None, out_classes_with_base=None, in_classes_with_base=[]): @@ -252,6 +576,7 @@ def _parse_stream_to_generator(f): pkg = None clazz = None blame = None + sig_format = 1 re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$") for raw in f: @@ -264,16 +589,18 @@ def _parse_stream_to_generator(f): else: blame = None - if raw.startswith("package"): + if line == 1 and raw == "// Signature format: 2.0": + sig_format = 2 + elif raw.startswith("package"): pkg = Package(line, raw, blame) elif raw.startswith(" ") and raw.endswith("{"): - clazz = Class(pkg, line, raw, blame) + clazz = Class(pkg, line, raw, blame, sig_format=sig_format) elif raw.startswith(" ctor"): - clazz.ctors.append(Method(clazz, line, raw, blame)) + clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format)) elif raw.startswith(" method"): - clazz.methods.append(Method(clazz, line, raw, blame)) + clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format)) elif raw.startswith(" field"): - clazz.fields.append(Field(clazz, line, raw, blame)) + clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format)) elif raw.startswith(" }") and clazz: yield clazz @@ -367,7 +694,7 @@ def _fail(clazz, detail, error, rule, msg): """Records an API failure to be processed later.""" global failures - sig = "%s-%s-%s" % (clazz.fullname, repr(detail), msg) + sig = "%s-%s-%s" % (clazz.fullname, detail.ident if detail else None, msg) sig = sig.replace(" deprecated ", " ") failures[sig] = Failure(sig, clazz, detail, error, rule, msg) @@ -408,7 +735,7 @@ def verify_constants(clazz): def verify_enums(clazz): """Enums are bad, mmkay?""" - if "extends java.lang.Enum" in clazz.raw: + if clazz.extends == "java.lang.Enum" or "enum" in clazz.split: error(clazz, None, "F5", "Enums are not allowed") @@ -467,7 +794,7 @@ def verify_listeners(clazz): interface OnFooListener { void onFoo() }""" if clazz.name.endswith("Listener"): - if " abstract class " in clazz.raw: + if "abstract" in clazz.split and "class" in clazz.split: error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback") for m in clazz.methods: @@ -546,16 +873,16 @@ def verify_equals(clazz): eq = False hc = False for m in clazz.methods: - if " static " in m.raw: continue - if "boolean equals(java.lang.Object)" in m.raw: eq = True - if "int hashCode()" in m.raw: hc = True + if "static" in m.split: continue + if m.sig_matches("boolean", "equals", ["java.lang.Object"]): eq = True + if m.sig_matches("int", "hashCode", []): hc = True if eq != hc: error(clazz, None, "M8", "Must override both equals and hashCode; missing one") def verify_parcelable(clazz): """Verify that Parcelable objects aren't hiding required bits.""" - if "implements android.os.Parcelable" in clazz.raw: + if clazz.implements == "android.os.Parcelable": creator = [ i for i in clazz.fields if i.name == "CREATOR" ] write = [ i for i in clazz.methods if i.name == "writeToParcel" ] describe = [ i for i in clazz.methods if i.name == "describeContents" ] @@ -563,8 +890,7 @@ def verify_parcelable(clazz): if len(creator) == 0 or len(write) == 0 or len(describe) == 0: error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one") - if ((" final class " not in clazz.raw) and - (" final deprecated class " not in clazz.raw)): + if "final" not in clazz.split: error(clazz, None, "FW8", "Parcelable classes must be final") for c in clazz.ctors: @@ -684,7 +1010,7 @@ def verify_helper_classes(clazz): """Verify that helper classes are named consistently with what they extend. All developer extendable methods should be named onFoo().""" test_methods = False - if "extends android.app.Service" in clazz.raw: + if clazz.extends == "android.app.Service": test_methods = True if not clazz.name.endswith("Service"): error(clazz, None, "CL4", "Inconsistent class name; should be FooService") @@ -696,7 +1022,7 @@ def verify_helper_classes(clazz): if f.value != clazz.fullname: error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname)) - if "extends android.content.ContentProvider" in clazz.raw: + if clazz.extends == "android.content.ContentProvider": test_methods = True if not clazz.name.endswith("Provider"): error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider") @@ -708,12 +1034,12 @@ def verify_helper_classes(clazz): if f.value != clazz.fullname: error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname)) - if "extends android.content.BroadcastReceiver" in clazz.raw: + if clazz.extends == "android.content.BroadcastReceiver": test_methods = True if not clazz.name.endswith("Receiver"): error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver") - if "extends android.app.Activity" in clazz.raw: + if clazz.extends == "android.app.Activity": test_methods = True if not clazz.name.endswith("Activity"): error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity") @@ -731,7 +1057,7 @@ def verify_helper_classes(clazz): def verify_builder(clazz): """Verify builder classes. Methods should return the builder to enable chaining.""" - if " extends " in clazz.raw: return + if clazz.extends: return if not clazz.name.endswith("Builder"): return if clazz.name != "Builder": @@ -759,7 +1085,7 @@ def verify_builder(clazz): def verify_aidl(clazz): """Catch people exposing raw AIDL.""" - if "extends android.os.Binder" in clazz.raw or "implements android.os.IInterface" in clazz.raw: + if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface": error(clazz, None, None, "Raw AIDL interfaces must not be exposed") @@ -768,48 +1094,66 @@ def verify_internal(clazz): if clazz.pkg.name.startswith("com.android"): error(clazz, None, None, "Internal classes must not be exposed") +def layering_build_ranking(ranking_list): + r = {} + for rank, ps in enumerate(ranking_list): + if not isinstance(ps, list): + ps = [ps] + for p in ps: + rs = r + for n in p.split('.'): + if n not in rs: + rs[n] = {} + rs = rs[n] + rs['-rank'] = rank + return r + +LAYERING_PACKAGE_RANKING = layering_build_ranking([ + ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], + "android.app", + "android.widget", + "android.view", + "android.animation", + "android.provider", + ["android.content","android.graphics.drawable"], + "android.database", + "android.text", + "android.graphics", + "android.os", + "android.util" +]) def verify_layering(clazz): """Catch package layering violations. For example, something in android.os depending on android.app.""" - ranking = [ - ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], - "android.app", - "android.widget", - "android.view", - "android.animation", - "android.provider", - ["android.content","android.graphics.drawable"], - "android.database", - "android.text", - "android.graphics", - "android.os", - "android.util" - ] def rank(p): - for i in range(len(ranking)): - if isinstance(ranking[i], list): - for j in ranking[i]: - if p.startswith(j): return i + r = None + l = LAYERING_PACKAGE_RANKING + for n in p.split('.'): + if n in l: + l = l[n] + if '-rank' in l: + r = l['-rank'] else: - if p.startswith(ranking[i]): return i + break + return r cr = rank(clazz.pkg.name) if cr is None: return for f in clazz.fields: ir = rank(f.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, f, "FW6", "Field type violates package layering") - for m in clazz.methods: + for m in itertools.chain(clazz.methods, clazz.ctors): ir = rank(m.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method return type violates package layering") for arg in m.args: ir = rank(arg) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method argument type violates package layering") @@ -900,21 +1244,18 @@ def verify_exception(clazz): if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]: warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException") +GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE) def verify_google(clazz): """Verifies that APIs never reference Google.""" - if re.search("google", clazz.raw, re.IGNORECASE): + if GOOGLE_IGNORECASE.search(clazz.raw) is not None: error(clazz, None, None, "Must never reference Google") - test = [] - test.extend(clazz.ctors) - test.extend(clazz.fields) - test.extend(clazz.methods) - - for t in test: - if re.search("google", t.raw, re.IGNORECASE): - error(clazz, t, None, "Must never reference Google") + for test in clazz.ctors, clazz.fields, clazz.methods: + for t in test: + if GOOGLE_IGNORECASE.search(t.raw) is not None: + error(clazz, t, None, "Must never reference Google") def verify_bitset(clazz): @@ -1168,7 +1509,7 @@ def verify_abstract_inner(clazz): """Verifies that abstract inner classes are static.""" if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname): - if " abstract " in clazz.raw and " static " not in clazz.raw: + if "abstract" in clazz.split and "static" not in clazz.split: warn(clazz, None, None, "Abstract inner classes should be static to improve testability") @@ -1263,8 +1604,8 @@ def verify_units(clazz): def verify_closable(clazz): """Verifies that classes are AutoClosable.""" - if "implements java.lang.AutoCloseable" in clazz.raw: return - if "implements java.io.Closeable" in clazz.raw: return + if clazz.implements == "java.lang.AutoCloseable": return + if clazz.implements == "java.io.Closeable": return for m in clazz.methods: if len(m.args) > 0: continue @@ -1350,6 +1691,9 @@ def verify_method_name_not_kotlin_operator(clazz): def verify_collections_over_arrays(clazz): """Warn that [] should be Collections.""" + if "@interface" in clazz.split: + return + safe = ["java.lang.String[]","byte[]","short[]","int[]","long[]","float[]","double[]","boolean[]","char[]"] for m in clazz.methods: if m.typ.endswith("[]") and m.typ not in safe: @@ -1683,11 +2027,11 @@ def show_deprecations_at_birth(cur, prev): del cur[prev_clazz.fullname] for clazz in cur.values(): - if " deprecated " in clazz.raw and not clazz.fullname in prev: + if "deprecated" in clazz.split and not clazz.fullname in prev: error(clazz, None, None, "Found API deprecation at birth") for i in clazz.ctors + clazz.methods + clazz.fields: - if " deprecated " in i.raw: + if "deprecated" in i.split: error(clazz, i, None, "Found API deprecation at birth") print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py index ece69a99f579..081e98defa17 100644 --- a/tools/apilint/apilint_test.py +++ b/tools/apilint/apilint_test.py @@ -143,5 +143,148 @@ class BaseFileTests(unittest.TestCase): out_classes_with_base=classes_with_base) self.assertEquals(map(lambda x: x.fullname, classes_with_base), ["android.app.WallpaperColors"]) +class V2TokenizerTests(unittest.TestCase): + def _test(self, raw, expected): + self.assertEquals(apilint.V2Tokenizer(raw).tokenize(), expected) + + def test_simple(self): + self._test(" method public some.Type someName(some.Argument arg, int arg);", + ['method', 'public', 'some.Type', 'someName', '(', 'some.Argument', + 'arg', ',', 'int', 'arg', ')', ';']) + self._test("class Some.Class extends SomeOther {", + ['class', 'Some.Class', 'extends', 'SomeOther', '{']) + + def test_varargs(self): + self._test("name(String...)", + ['name', '(', 'String', '...', ')']) + + def test_kotlin(self): + self._test("String? name(String!...)", + ['String', '?', 'name', '(', 'String', '!', '...', ')']) + + def test_annotation(self): + self._test("method @Nullable public void name();", + ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';']) + + def test_annotation_args(self): + self._test("@Some(val=1, other=2) class Class {", + ['@', 'Some', '(', 'val', '=', '1', ',', 'other', '=', '2', ')', + 'class', 'Class', '{']) + def test_comment(self): + self._test("some //comment", ['some']) + + def test_strings(self): + self._test(r'"" "foo" "\"" "\\"', ['""', '"foo"', r'"\""', r'"\\"']) + + def test_at_interface(self): + self._test("public @interface Annotation {", + ['public', '@interface', 'Annotation', '{']) + + def test_array_type(self): + self._test("int[][]", ['int', '[]', '[]']) + + def test_generics(self): + self._test("<>foobar<A extends Object>", + ['<', '>', 'foobar', '<', 'A', 'extends', 'Object', '>']) + +class V2ParserTests(unittest.TestCase): + def _cls(self, raw): + pkg = apilint.Package(999, "package pkg {", None) + return apilint.Class(pkg, 1, raw, '', sig_format=2) + + def _method(self, raw, cls=None): + if not cls: + cls = self._cls("class Class {") + return apilint.Method(cls, 1, raw, '', sig_format=2) + + def _field(self, raw): + cls = self._cls("class Class {") + return apilint.Field(cls, 1, raw, '', sig_format=2) + + def test_class(self): + cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {") + self.assertTrue('deprecated' in cls.split) + self.assertTrue('static' in cls.split) + self.assertTrue('abstract' in cls.split) + self.assertTrue('class' in cls.split) + self.assertEquals('Super', cls.extends) + self.assertEquals('Interface', cls.implements) + self.assertEquals('pkg.Some.Name', cls.fullname) + + def test_interface(self): + cls = self._cls("@Deprecated @IntRange(from=1, to=2) public interface Some.Name extends Interface<Class> {") + self.assertTrue('deprecated' in cls.split) + self.assertTrue('interface' in cls.split) + self.assertEquals('Interface', cls.extends) + self.assertEquals('Interface', cls.implements) + self.assertEquals('pkg.Some.Name', cls.fullname) + + def test_at_interface(self): + cls = self._cls("@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SuppressLint {") + self.assertTrue('@interface' in cls.split) + self.assertEquals('pkg.SuppressLint', cls.fullname) + + def test_parse_method(self): + m = self._method("method @Deprecated public static <T> Class<T>[][] name(" + + "Class<T[]>[][], Class<T[][][]>[][]...) throws Exception, T;") + self.assertTrue('static' in m.split) + self.assertTrue('public' in m.split) + self.assertTrue('method' in m.split) + self.assertTrue('deprecated' in m.split) + self.assertEquals('java.lang.Class[][]', m.typ) + self.assertEquals('name', m.name) + self.assertEquals(['java.lang.Class[][]', 'java.lang.Class[][]...'], m.args) + self.assertEquals(['java.lang.Exception', 'T'], m.throws) + + def test_ctor(self): + m = self._method("ctor @Deprecated <T> ClassName();") + self.assertTrue('ctor' in m.split) + self.assertTrue('deprecated' in m.split) + self.assertEquals('ctor', m.typ) + self.assertEquals('ClassName', m.name) + + def test_parse_annotation_method(self): + cls = self._cls("@interface Annotation {") + self._method('method abstract String category() default "";', cls=cls) + self._method('method abstract boolean deepExport() default false;', cls=cls) + self._method('method abstract ViewDebug.FlagToString[] flagMapping() default {};', cls=cls) + + def test_parse_string_field(self): + f = self._field('field @Deprecated public final String SOME_NAME = "value";') + self.assertTrue('field' in f.split) + self.assertTrue('deprecated' in f.split) + self.assertTrue('final' in f.split) + self.assertEquals('java.lang.String', f.typ) + self.assertEquals('SOME_NAME', f.name) + self.assertEquals('value', f.value) + + def test_parse_field(self): + f = self._field('field public Object SOME_NAME;') + self.assertTrue('field' in f.split) + self.assertEquals('java.lang.Object', f.typ) + self.assertEquals('SOME_NAME', f.name) + self.assertEquals(None, f.value) + + def test_parse_int_field(self): + f = self._field('field public int NAME = 123;') + self.assertTrue('field' in f.split) + self.assertEquals('int', f.typ) + self.assertEquals('NAME', f.name) + self.assertEquals('123', f.value) + + def test_parse_quotient_field(self): + f = self._field('field public int NAME = (0.0/0.0);') + self.assertTrue('field' in f.split) + self.assertEquals('int', f.typ) + self.assertEquals('NAME', f.name) + self.assertEquals('( 0.0 / 0.0 )', f.value) + + def test_kotlin_types(self): + self._field('field public List<Integer[]?[]!>?[]![]? NAME;') + self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname," + + "Class<T?>[][]?[]!...!) throws Exception, T;") + self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, " + + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""") + if __name__ == "__main__": - unittest.main()
\ No newline at end of file + unittest.main() diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1700006f939d..7b2f07d5cb68 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -16,7 +16,6 @@ package android.net.wifi; - import android.content.pm.ParceledListSlice; import android.net.wifi.hotspot2.OsuProvider; @@ -63,7 +62,7 @@ interface IWifiManager ParceledListSlice getPrivilegedConfiguredNetworks(); - List<WifiConfiguration> getAllMatchingWifiConfigs(in List<ScanResult> scanResult); + Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult); List<OsuProvider> getMatchingOsuProviders(in List<ScanResult> scanResult); @@ -77,6 +76,8 @@ interface IWifiManager List<PasspointConfiguration> getPasspointConfigurations(); + List<WifiConfiguration> getWifiConfigsForPasspointProfiles(in List<String> fqdnList); + void queryPasspointIcon(long bssid, String fileName); int matchProviderWithCurrentNetwork(String fqdn); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e67e8ea7d9ab..f2a3b42e1668 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -44,6 +44,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.os.WorkSource; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; @@ -1191,25 +1192,39 @@ public class WifiManager { } /** - * Returns all matching WifiConfigurations for a given list of ScanResult. + * Returns a list of all matching WifiConfigurations for a given list of ScanResult. * * An empty list will be returned when no configurations are installed or if no configurations * match the ScanResult. - + * * @param scanResults a list of scanResult that represents the BSSID - * @return A list of {@link WifiConfiguration} that can have duplicate entries. + * @return List that consists of {@link WifiConfiguration} and corresponding scanResults. * @throws UnsupportedOperationException if Passpoint is not enabled on the device. * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public List<WifiConfiguration> getAllMatchingWifiConfigs( + public List<Pair<WifiConfiguration, List<ScanResult>>> getAllMatchingWifiConfigs( @NonNull List<ScanResult> scanResults) { + List<Pair<WifiConfiguration, List<ScanResult>>> configs = new ArrayList<>(); try { - return mService.getAllMatchingWifiConfigs(scanResults); + Map<String, List<ScanResult>> results = mService.getAllMatchingFqdnsForScanResults( + scanResults); + if (results.isEmpty()) { + return configs; + } + List<WifiConfiguration> wifiConfigurations = + mService.getWifiConfigsForPasspointProfiles(new ArrayList<>(results.keySet())); + for (WifiConfiguration configuration : wifiConfigurations) { + List<ScanResult> scanResultList = results.get(configuration.FQDN); + if (scanResultList != null) { + configs.add(Pair.create(configuration, scanResultList)); + } + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + + return configs; } /** diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 01feb1ef5b42..72e57a16712b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -17,15 +17,15 @@ package android.net.wifi.p2p; import android.annotation.UnsupportedAppUsage; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import java.util.ArrayList; -import java.util.List; import java.util.Collection; import java.util.Collections; -import java.util.regex.Pattern; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A class representing a Wi-Fi P2p group. A p2p group consists of a single group @@ -67,6 +67,9 @@ public class WifiP2pGroup implements Parcelable { /** The network id in the wpa_supplicant */ private int mNetId; + /** The frequency used by this group */ + private int mFrequency; + /** P2P group started string pattern */ private static final Pattern groupStartedPattern = Pattern.compile( "ssid=\"(.+)\" " + @@ -116,8 +119,9 @@ public class WifiP2pGroup implements Parcelable { } mNetworkName = match.group(1); - //freq and psk are unused right now - //int freq = Integer.parseInt(match.group(2)); + // It throws NumberFormatException if the string cannot be parsed as an integer. + mFrequency = Integer.parseInt(match.group(2)); + // psk is unused right now //String psk = match.group(3); mPassphrase = match.group(4); mOwner = new WifiP2pDevice(match.group(5)); @@ -269,6 +273,16 @@ public class WifiP2pGroup implements Parcelable { this.mNetId = netId; } + /** Get the operating frequency of the p2p group */ + public int getFrequency() { + return mFrequency; + } + + /** @hide */ + public void setFrequency(int freq) { + this.mFrequency = freq; + } + public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("network: ").append(mNetworkName); @@ -279,6 +293,7 @@ public class WifiP2pGroup implements Parcelable { } sbuf.append("\n interface: ").append(mInterface); sbuf.append("\n networkId: ").append(mNetId); + sbuf.append("\n frequency: ").append(mFrequency); return sbuf.toString(); } @@ -297,6 +312,7 @@ public class WifiP2pGroup implements Parcelable { mPassphrase = source.getPassphrase(); mInterface = source.getInterface(); mNetId = source.getNetworkId(); + mFrequency = source.getFrequency(); } } @@ -312,6 +328,7 @@ public class WifiP2pGroup implements Parcelable { dest.writeString(mPassphrase); dest.writeString(mInterface); dest.writeInt(mNetId); + dest.writeInt(mFrequency); } /** Implement the Parcelable interface */ @@ -329,6 +346,7 @@ public class WifiP2pGroup implements Parcelable { group.setPassphrase(in.readString()); group.setInterface(in.readString()); group.setNetworkId(in.readInt()); + group.setFrequency(in.readInt()); return group; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 068b959f14ca..1bed914c7772 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -1281,7 +1281,16 @@ public class WifiP2pManager { c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener)); } - /** @hide */ + /** + * Force p2p to enter or exit listen state + * + * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} + * @param enable enables or disables listening + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void listen(Channel c, boolean enable, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN, diff --git a/wifi/java/com/android/server/wifi/AbstractWifiService.java b/wifi/java/com/android/server/wifi/AbstractWifiService.java index e94b9e6c8671..23961080110e 100644 --- a/wifi/java/com/android/server/wifi/AbstractWifiService.java +++ b/wifi/java/com/android/server/wifi/AbstractWifiService.java @@ -106,7 +106,8 @@ public abstract class AbstractWifiService extends IWifiManager.Stub { } @Override - public List<WifiConfiguration> getAllMatchingWifiConfigs(List<ScanResult> scanResults) { + public Map<String, List<ScanResult>> getAllMatchingFqdnsForScanResults( + List<ScanResult> scanResults) { throw new UnsupportedOperationException(); } @@ -155,6 +156,11 @@ public abstract class AbstractWifiService extends IWifiManager.Stub { } @Override + public List<WifiConfiguration> getWifiConfigsForPasspointProfiles(List<String> fqdnList) { + throw new UnsupportedOperationException(); + } + + @Override public void queryPasspointIcon(long bssid, String fileName) { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index c43948bb0c04..4fbef5a8493d 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -77,7 +77,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Unit tests for {@link android.net.wifi.WifiManager}. @@ -1274,14 +1276,20 @@ i * Verify that a call to cancel WPS immediately returns a failure. } /** - * Check the call to getAllMatchingWifiConfigs calls getAllMatchingWifiConfigs of WifiService - * with the provided a list of ScanResult. + * Check the call to getAllMatchingWifiConfigs calls getAllMatchingFqdnsForScanResults and + * getWifiConfigsForPasspointProfiles of WifiService in order. */ @Test public void testGetAllMatchingWifiConfigs() throws Exception { + Map<String, List<ScanResult>> fqdns = new HashMap<>(); + fqdns.put("www.test.com", new ArrayList<>()); + when(mWifiService.getAllMatchingFqdnsForScanResults(any(List.class))).thenReturn(fqdns); + InOrder inOrder = inOrder(mWifiService); + mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>()); - verify(mWifiService).getAllMatchingWifiConfigs(any(List.class)); + inOrder.verify(mWifiService).getAllMatchingFqdnsForScanResults(any(List.class)); + inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class)); } /** |