Merge "ScrimController: Wait with clearing wakup animation until done" into oc-dr1-dev
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 44c88e1..1a2968f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -65,7 +65,8 @@
private static native void nativeSetSize(long nativeObject, int w, int h);
private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
private static native void nativeSetAlpha(long nativeObject, float alpha);
- private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
+ private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+ float dtdy, float dsdy);
private static native void nativeSetFlags(long nativeObject, int flags, int mask);
private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index 7fafef7..3a81c13 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -28,4 +28,6 @@
<backup-transport-whitelisted-service
service="android/com.android.internal.backup.LocalTransportService" />
+ <!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
+ <app-link package="com.android.carrierdefaultapp" />
</config>
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index c309133..1cd7b61 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -34,6 +34,7 @@
<intent-filter>
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+ <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
@@ -43,10 +44,24 @@
android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
android:label="@string/action_bar_label"
android:theme="@style/AppTheme"
- android:configChanges="keyboardHidden|orientation|screenSize" >
+ android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+
+ <activity-alias
+ android:name="com.android.carrierdefaultapp.URLHandlerActivity"
+ android:targetActivity="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+ android:enabled="false" >
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ <data android:host="*" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 6194b87..b0052cc 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -20,6 +20,9 @@
import android.app.LoadedApk;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
@@ -34,6 +37,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
@@ -68,7 +72,7 @@
private static final boolean DBG = true;
private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
- public static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
+ private static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
private URL mUrl;
private Network mNetwork;
@@ -188,16 +192,19 @@
CarrierActionUtils.applyCarrierAction(
CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
getApplicationContext());
-
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER, getIntent(),
+ getApplicationContext());
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL, getIntent(),
+ getApplicationContext());
}
finishAndRemoveTask();
}
private URL getUrlForCaptivePortal() {
String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
- if (url.isEmpty()) {
- url = mCm.getCaptivePortalServerUrl();
- }
+ if (TextUtils.isEmpty(url)) url = mCm.getCaptivePortalServerUrl();
final CarrierConfigManager configManager = getApplicationContext()
.getSystemService(CarrierConfigManager.class);
final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
@@ -437,6 +444,27 @@
}
}
+ /**
+ * This alias presents the target activity, CaptivePortalLoginActivity, as a independent
+ * entity with its own intent filter to handle URL links. This alias will be enabled/disabled
+ * dynamically to handle url links based on the network conditions.
+ */
+ public static String getAlias(Context context) {
+ try {
+ PackageInfo p = context.getPackageManager().getPackageInfo(context.getPackageName(),
+ PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS);
+ for (ActivityInfo activityInfo : p.activities) {
+ String targetActivity = activityInfo.targetActivity;
+ if (CaptivePortalLoginActivity.class.getName().equals(targetActivity)) {
+ return activityInfo.name;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
private static void logd(String s) {
Rlog.d(TAG, s);
}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 0213306..a2bf964 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -19,8 +19,10 @@
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.telephony.SubscriptionManager;
@@ -49,6 +51,10 @@
public static final int CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION = 4;
public static final int CARRIER_ACTION_SHOW_NO_DATA_SERVICE_NOTIFICATION = 5;
public static final int CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS = 6;
+ public static final int CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER = 7;
+ public static final int CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER = 8;
+ public static final int CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL = 9;
+ public static final int CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL = 10;
public static void applyCarrierAction(int actionIdx, Intent intent, Context context) {
switch (actionIdx) {
@@ -73,6 +79,18 @@
case CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS:
onCancelAllNotifications(context);
break;
+ case CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER:
+ onEnableDefaultURLHandler(context);
+ break;
+ case CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER:
+ onDisableDefaultURLHandler(context);
+ break;
+ case CARRIER_ACTION_REGISTER_DEFAULT_NETWORK_AVAIL:
+ onRegisterDefaultNetworkAvail(intent, context);
+ break;
+ case CARRIER_ACTION_DEREGISTER_DEFAULT_NETWORK_AVAIL:
+ onDeregisterDefaultNetworkAvail(intent, context);
+ break;
default:
loge("unsupported carrier action index: " + actionIdx);
}
@@ -94,6 +112,38 @@
telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
}
+ private static void onEnableDefaultURLHandler(Context context) {
+ logd("onEnableDefaultURLHandler");
+ final PackageManager pm = context.getPackageManager();
+ pm.setComponentEnabledSetting(
+ new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
+ }
+
+ private static void onDisableDefaultURLHandler(Context context) {
+ logd("onDisableDefaultURLHandler");
+ final PackageManager pm = context.getPackageManager();
+ pm.setComponentEnabledSetting(
+ new ComponentName(context, CaptivePortalLoginActivity.getAlias(context)),
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
+ }
+
+ private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) {
+ int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultVoiceSubscriptionId());
+ logd("onRegisterDefaultNetworkAvail subId: " + subId);
+ final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+ telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, true);
+ }
+
+ private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) {
+ int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultVoiceSubscriptionId());
+ logd("onDeregisterDefaultNetworkAvail subId: " + subId);
+ final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+ telephonyMgr.carrierActionReportDefaultNetworkStatus(subId, false);
+ }
+
private static void onDisableRadio(Intent intent, Context context) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.getDefaultVoiceSubscriptionId());
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
index d5d0b79..02c61d7 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
@@ -22,7 +22,6 @@
import android.telephony.Rlog;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;
@@ -95,6 +94,12 @@
configs = b.getStringArray(CarrierConfigManager
.KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET);
break;
+ case TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE:
+ configs = b.getStringArray(CarrierConfigManager
+ .KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE);
+ arg1 = String.valueOf(intent.getBooleanExtra(TelephonyIntents
+ .EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY, false));
+ break;
default:
Rlog.e(TAG, "load carrier config failure with un-configured key: " +
intent.getAction());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
index 1240e05..cc7798e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
@@ -31,4 +31,5 @@
void sendRecentsDrawnEvent();
void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
void sendLaunchRecentsEvent();
+ void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index de2ace4..86dde54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -54,9 +54,11 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.events.component.ShowUserToastEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -612,6 +614,14 @@
}
});
}
+
+ // This will catch the cases when a user launches from recents to another app
+ // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
+ // would not reset the wait for transition flag. This will catch it and make sure that the
+ // flag is reset.
+ if (!event.visible) {
+ mImpl.setWaitingForTransitionStart(false);
+ }
}
/**
@@ -684,6 +694,11 @@
}
}
+ public final void onBusEvent(LaunchTaskFailedEvent event) {
+ // Reset the transition when tasks fail to launch
+ mImpl.setWaitingForTransitionStart(false);
+ }
+
public final void onBusEvent(ConfigurationChangedEvent event) {
// Update the configuration for the Recents component when the activity configuration
// changes as well
@@ -711,6 +726,25 @@
}
}
+ public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
+ int processUser = sSystemServicesProxy.getProcessUser();
+ if (sSystemServicesProxy.isSystemUser(processUser)) {
+ mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
+ } else {
+ postToSystemUser(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
+ event.waitingForTransitionStart);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Callback failed", e);
+ }
+ }
+ });
+ }
+ }
+
/**
* Attempts to register with the system user.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 7cd93bb..86e93fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -24,12 +24,11 @@
import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityOptions;
+import android.app.ActivityOptions.OnAnimationStartedListener;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -208,6 +207,20 @@
protected static RecentsTaskLoadPlan sInstanceLoadPlan;
// Stores the last pinned task time
protected static long sLastPipTime = -1;
+ // Stores whether we are waiting for a transition to/from recents to start. During this time,
+ // we disallow the user from manually toggling recents until the transition has started.
+ private static boolean mWaitingForTransitionStart = false;
+ // Stores whether or not the user toggled while we were waiting for a transition to/from
+ // recents. In this case, we defer the toggle state until then and apply it immediately after.
+ private static boolean mToggleFollowingTransitionStart = true;
+
+ private ActivityOptions.OnAnimationStartedListener mResetToggleFlagListener =
+ new OnAnimationStartedListener() {
+ @Override
+ public void onAnimationStarted() {
+ setWaitingForTransitionStart(false);
+ }
+ };
protected Context mContext;
protected Handler mHandler;
@@ -365,6 +378,11 @@
return;
}
+ if (mWaitingForTransitionStart) {
+ mToggleFollowingTransitionStart = true;
+ return;
+ }
+
mDraggingInRecents = false;
mLaunchedWhileDocking = false;
mTriggeredFromAltTab = false;
@@ -638,6 +656,18 @@
}
}
+ public void setWaitingForTransitionStart(boolean waitingForTransitionStart) {
+ if (mWaitingForTransitionStart == waitingForTransitionStart) {
+ return;
+ }
+
+ mWaitingForTransitionStart = waitingForTransitionStart;
+ if (!waitingForTransitionStart && mToggleFollowingTransitionStart) {
+ toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET);
+ }
+ mToggleFollowingTransitionStart = false;
+ }
+
/**
* Returns the preloaded load plan and invalidates it.
*/
@@ -865,8 +895,9 @@
}
AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
specs.toArray(specsArray);
+
return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
- specsArray, mHandler, null, this), null);
+ specsArray, mHandler, mResetToggleFlagListener, this), null);
} else {
// Update the destination rect
Task toTask = new Task();
@@ -884,8 +915,10 @@
return Lists.newArrayList(new AppTransitionAnimationSpec(
toTask.key.id, thumbnail, rect));
});
+
return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
- mHandler, future.getFuture(), null, false /* scaleUp */), future);
+ mHandler, future.getFuture(), mResetToggleFlagListener, false /* scaleUp */),
+ future);
}
}
@@ -991,6 +1024,10 @@
launchState.launchedToTaskId = runningTaskId;
launchState.launchedWithAltTab = mTriggeredFromAltTab;
+ // Disable toggling of recents between starting the activity and it is visible and the app
+ // has started its transition into recents.
+ setWaitingForTransitionStart(useThumbnailTransition);
+
// Preload the icon (this will be a null-op if we have preloaded the icon already in
// preloadRecents())
preloadIcon(runningTaskId);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index 3921a20..1285626 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -29,6 +29,7 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.misc.ForegroundThread;
@@ -105,4 +106,10 @@
public void sendLaunchRecentsEvent() throws RemoteException {
EventBus.getDefault().post(new RecentsActivityStartingEvent());
}
+
+ @Override
+ public void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+ EventBus.getDefault().post(new SetWaitingForTransitionStartEvent(
+ waitingForTransitionStart));
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
new file mode 100644
index 0000000..d9cf5fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
@@ -0,0 +1,31 @@
+/*
+ * 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.recents.events.component;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when we are setting/resetting the flag to wait for the transition to start.
+ */
+public class SetWaitingForTransitionStartEvent extends EventBus.Event {
+
+ public final boolean waitingForTransitionStart;
+
+ public SetWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
+ this.waitingForTransitionStart = waitingForTransitionStart;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 968b77f..67685b8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -54,6 +54,7 @@
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
@@ -117,31 +118,58 @@
final Rect windowRect = Recents.getSystemServices().getWindowRect();
transitionFuture = getAppTransitionFuture(
() -> composeAnimationSpecs(task, stackView, destinationStack, windowRect));
- animStartedListener = () -> {
- // If we are launching into another task, cancel the previous task's
- // window transition
- EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
- EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
- stackView.cancelAllTaskViewAnimations();
+ animStartedListener = new OnAnimationStartedListener() {
+ private boolean mHandled;
- if (screenPinningRequested) {
- // Request screen pinning after the animation runs
- mStartScreenPinningRunnable.taskId = task.key.id;
- mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+ @Override
+ public void onAnimationStarted() {
+ if (mHandled) {
+ return;
+ }
+ mHandled = true;
+
+ // If we are launching into another task, cancel the previous task's
+ // window transition
+ EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+ EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+ stackView.cancelAllTaskViewAnimations();
+
+ if (screenPinningRequested) {
+ // Request screen pinning after the animation runs
+ mStartScreenPinningRunnable.taskId = task.key.id;
+ mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+ }
+
+ // Reset the state where we are waiting for the transition to start
+ EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
}
};
} else {
// This is only the case if the task is not on screen (scrolled offscreen for example)
transitionFuture = null;
- animStartedListener = () -> {
- // If we are launching into another task, cancel the previous task's
- // window transition
- EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
- EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
- stackView.cancelAllTaskViewAnimations();
+ animStartedListener = new OnAnimationStartedListener() {
+ private boolean mHandled;
+
+ @Override
+ public void onAnimationStarted() {
+ if (mHandled) {
+ return;
+ }
+ mHandled = true;
+
+ // If we are launching into another task, cancel the previous task's
+ // window transition
+ EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+ EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
+ stackView.cancelAllTaskViewAnimations();
+
+ // Reset the state where we are waiting for the transition to start
+ EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
+ }
};
}
+ EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(true));
final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
mHandler, transitionFuture != null ? transitionFuture.future : null,
animStartedListener, true /* scaleUp */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 4bbe895..291ec1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3714,6 +3714,9 @@
* See {@link AmbientState#setDark}.
*/
public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
+ if (mAmbientState.isDark() == dark) {
+ return;
+ }
mAmbientState.setDark(dark);
if (animate && mAnimationsEnabled) {
mDarkNeedsAnimation = true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 38327bc..84017e7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13367,7 +13367,6 @@
final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r != null) {
final ActivityOptions activityOptions = r.pendingOptions;
- r.pendingOptions = null;
return activityOptions == null ? null : activityOptions.toBundle();
}
return null;
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index cdf25cf..11a4eb4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -543,7 +543,9 @@
loadPropertiesFromResource(context, mProperties);
String lpp_profile = mProperties.getProperty("LPP_PROFILE");
// set the persist property LPP_PROFILE for the value
- SystemProperties.set(LPP_PROFILE, lpp_profile);
+ if (lpp_profile != null) {
+ SystemProperties.set(LPP_PROFILE, lpp_profile);
+ }
} else {
// reset the persist property
SystemProperties.set(LPP_PROFILE, "");
diff --git a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
index 0508fdf..a12c2c4 100644
--- a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
+++ b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
@@ -32,7 +32,7 @@
// the surface control.
//
// See cts/hostsidetests/../../SurfaceTraceReceiver.java for parsing side.
-class RemoteSurfaceTrace extends SurfaceControl {
+class RemoteSurfaceTrace extends SurfaceControlWithBackground {
static final String TAG = "RemoteSurfaceTrace";
final FileDescriptor mWriteFd;
@@ -41,7 +41,8 @@
final WindowManagerService mService;
final WindowState mWindow;
- RemoteSurfaceTrace(FileDescriptor fd, SurfaceControl wrapped, WindowState window) {
+ RemoteSurfaceTrace(FileDescriptor fd, SurfaceControlWithBackground wrapped,
+ WindowState window) {
super(wrapped);
mWriteFd = fd;
diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
new file mode 100644
index 0000000..f5ef2e6
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
@@ -0,0 +1,306 @@
+/*
+ * 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.wm;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+/**
+ * SurfaceControl extension that has background sized to match its container.
+ */
+class SurfaceControlWithBackground extends SurfaceControl {
+ // SurfaceControl that holds the background behind opaque letterboxed app windows.
+ private SurfaceControl mBackgroundControl;
+
+ // Flags that define whether the background should be shown.
+ private boolean mOpaque;
+ private boolean mVisible;
+
+ // Way to communicate with corresponding window.
+ private WindowSurfaceController mWindowSurfaceController;
+
+ // Rect to hold task bounds when computing metrics for background.
+ private Rect mTmpContainerRect = new Rect();
+
+ // Last metrics applied to the main SurfaceControl.
+ private float mLastWidth, mLastHeight;
+ private float mLastDsDx = 1, mLastDsDy = 1;
+ private float mLastX, mLastY;
+
+ public SurfaceControlWithBackground(SurfaceControlWithBackground other) {
+ super(other);
+ mBackgroundControl = other.mBackgroundControl;
+ mOpaque = other.mOpaque;
+ mVisible = other.mVisible;
+ mWindowSurfaceController = other.mWindowSurfaceController;
+ }
+
+ public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format,
+ int flags, int windowType, int ownerUid,
+ WindowSurfaceController windowSurfaceController) throws OutOfResourcesException {
+ super(s, name, w, h, format, flags, windowType, ownerUid);
+
+ // We should only show background when the window is letterboxed in a task.
+ if (!windowSurfaceController.mAnimator.mWin.isLetterboxedAppWindow()) {
+ return;
+ }
+ mWindowSurfaceController = windowSurfaceController;
+ mLastWidth = w;
+ mLastHeight = h;
+ mOpaque = (flags & SurfaceControl.OPAQUE) != 0;
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl = new SurfaceControl(s, "Background for - " + name,
+ mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE,
+ flags | SurfaceControl.FX_SURFACE_DIM);
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ super.setAlpha(alpha);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setAlpha(alpha);
+ }
+
+ @Override
+ public void setLayer(int zorder) {
+ super.setLayer(zorder);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ // TODO: Use setRelativeLayer(Integer.MIN_VALUE) when it's fixed.
+ mBackgroundControl.setLayer(zorder - 1);
+ }
+
+ @Override
+ public void setPosition(float x, float y) {
+ super.setPosition(x, y);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mLastX = x;
+ mLastY = y;
+ updateBgPosition();
+ }
+
+ private void updateBgPosition() {
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+ final float offsetX = (mTmpContainerRect.left - winFrame.left) * mLastDsDx;
+ final float offsetY = (mTmpContainerRect.top - winFrame.top) * mLastDsDy;
+ mBackgroundControl.setPosition(mLastX + offsetX, mLastY + offsetY);
+ }
+
+ @Override
+ public void setSize(int w, int h) {
+ super.setSize(w, h);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mLastWidth = w;
+ mLastHeight = h;
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setSize(mTmpContainerRect.width(), mTmpContainerRect.height());
+ }
+
+ @Override
+ public void setWindowCrop(Rect crop) {
+ super.setWindowCrop(crop);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
+ // We're animating and cropping window, compute the appropriate crop for background.
+ calculateBgCrop(crop);
+ mBackgroundControl.setWindowCrop(mTmpContainerRect);
+ } else {
+ // When not animating just set crop to container rect.
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setWindowCrop(mTmpContainerRect);
+ }
+ }
+
+ @Override
+ public void setFinalCrop(Rect crop) {
+ super.setFinalCrop(crop);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
+ // We're animating and cropping window, compute the appropriate crop for background.
+ calculateBgCrop(crop);
+ mBackgroundControl.setFinalCrop(mTmpContainerRect);
+ } else {
+ // When not animating just set crop to container rect.
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setFinalCrop(mTmpContainerRect);
+ }
+ }
+
+ /** Compute background crop based on current animation progress for main surface control. */
+ private void calculateBgCrop(Rect crop) {
+ // Track overall progress of animation by computing cropped portion of status bar.
+ final Rect contentInsets = mWindowSurfaceController.mAnimator.mWin.mContentInsets;
+ float d = contentInsets.top == 0 ? 0 : (float) crop.top / contentInsets.top;
+
+ // Compute additional offset for the background when app window is positioned not at (0,0).
+ // E.g. landscape with navigation bar on the left.
+ final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+ final int offsetX = (int) (winFrame.left * mLastDsDx * d + 0.5);
+ final int offsetY = (int) (winFrame.top * mLastDsDy * d + 0.5);
+
+ // Compute new scaled width and height for background that will depend on current animation
+ // progress. Those consist of current crop rect for the main surface + scaled areas outside
+ // of letterboxed area.
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ final int backgroundWidth =
+ (int) (crop.width() + (mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+ final int backgroundHeight =
+ (int) (crop.height() + (mTmpContainerRect.height() - mLastHeight) * (1 - d) + 0.5);
+
+ mTmpContainerRect.set(crop);
+ // Make sure that part of background to left/top is visible and scaled.
+ mTmpContainerRect.offset(offsetX, offsetY);
+ // Set correct width/height, so that area to right/bottom is cropped properly.
+ mTmpContainerRect.right = mTmpContainerRect.left + backgroundWidth;
+ mTmpContainerRect.bottom = mTmpContainerRect.top + backgroundHeight;
+ }
+
+ @Override
+ public void setLayerStack(int layerStack) {
+ super.setLayerStack(layerStack);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setLayerStack(layerStack);
+ }
+
+ @Override
+ public void setOpaque(boolean isOpaque) {
+ super.setOpaque(isOpaque);
+ mOpaque = isOpaque;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void setSecure(boolean isSecure) {
+ super.setSecure(isSecure);
+ }
+
+ @Override
+ public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
+ super.setMatrix(dsdx, dtdx, dtdy, dsdy);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
+ mLastDsDx = dsdx;
+ mLastDsDy = dsdy;
+ updateBgPosition();
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ mVisible = false;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void show() {
+ super.show();
+ mVisible = true;
+ updateBackgroundVisibility();
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.destroy();
+ }
+
+ @Override
+ public void release() {
+ super.release();
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.release();
+ }
+
+ @Override
+ public void setTransparentRegionHint(Region region) {
+ super.setTransparentRegionHint(region);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.setTransparentRegionHint(region);
+ }
+
+ @Override
+ public void deferTransactionUntil(IBinder handle, long frame) {
+ super.deferTransactionUntil(handle, frame);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.deferTransactionUntil(handle, frame);
+ }
+
+ @Override
+ public void deferTransactionUntil(Surface barrier, long frame) {
+ super.deferTransactionUntil(barrier, frame);
+
+ if (mBackgroundControl == null) {
+ return;
+ }
+ mBackgroundControl.deferTransactionUntil(barrier, frame);
+ }
+
+ private void updateBackgroundVisibility() {
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if (mOpaque && mVisible) {
+ mBackgroundControl.show();
+ } else {
+ mBackgroundControl.hide();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c968653..02242f3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3219,6 +3219,15 @@
return !isInMultiWindowMode();
}
+ /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+ boolean isLetterboxedAppWindow() {
+ final Task task = getTask();
+ final boolean taskIsFullscreen = task != null && task.isFullscreen();
+ final boolean appWindowIsFullscreen = mAppToken != null && !mAppToken.hasBounds();
+
+ return taskIsFullscreen && !appWindowIsFullscreen;
+ }
+
/** Returns the appropriate bounds to use for computing frames. */
private void getContainerBounds(Rect outBounds) {
if (isInMultiWindowMode()) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 0cc505e..86265c29 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1200,7 +1200,8 @@
if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
+ w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
- final boolean fullscreen = w.fillsDisplay();
+ final Task task = w.getTask();
+ final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
final boolean isFreeformResizing =
w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
@@ -1526,6 +1527,19 @@
}
}
+ /**
+ * Get rect of the task this window is currently in. If there is no task, rect will be set to
+ * empty.
+ */
+ void getContainerRect(Rect rect) {
+ final Task task = mWin.getTask();
+ if (task != null) {
+ task.getDimBounds(rect);
+ } else {
+ rect.left = rect.top = rect.right = rect.bottom = 0;
+ }
+ }
+
void prepareSurfaceLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
if (!hasSurface()) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 27927e6..4819c0f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -52,7 +52,7 @@
final WindowStateAnimator mAnimator;
- private SurfaceControl mSurfaceControl;
+ private SurfaceControlWithBackground mSurfaceControl;
// Should only be set from within setShown().
private boolean mSurfaceShown = false;
@@ -99,15 +99,10 @@
mWindowType = windowType;
mWindowSession = win.mSession;
- if (DEBUG_SURFACE_TRACE) {
- mSurfaceControl = new SurfaceTrace(
- s, name, w, h, format, flags, windowType, ownerUid);
- } else {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
- mSurfaceControl = new SurfaceControl(
- s, name, w, h, format, flags, windowType, ownerUid);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- }
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
+ mSurfaceControl = new SurfaceControlWithBackground(
+ s, name, w, h, format, flags, windowType, ownerUid, this);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (mService.mRoot.mSurfaceTraceEnabled) {
mSurfaceControl = new RemoteSurfaceTrace(
@@ -120,7 +115,7 @@
}
void removeRemoteTrace() {
- mSurfaceControl = new SurfaceControl(mSurfaceControl);
+ mSurfaceControl = new SurfaceControlWithBackground(mSurfaceControl);
}
@@ -293,30 +288,30 @@
mSurfaceControl.setGeometryAppliesWithResize();
}
- void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
+ void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
boolean recoveringMemory) {
final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
- mLastDsdy != dsdy || mLastDtdy != dtdy;
+ mLastDtdy != dtdy || mLastDsdy != dsdy;
if (!matrixChanged) {
return;
}
mLastDsdx = dsdx;
mLastDtdx = dtdx;
- mLastDsdy = dsdy;
mLastDtdy = dtdy;
+ mLastDsdy = dsdy;
try {
if (SHOW_TRANSACTIONS) logSurface(
- "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+ "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
mSurfaceControl.setMatrix(
- dsdx, dtdx, dsdy, dtdy);
+ dsdx, dtdx, dtdy, dsdy);
} catch (RuntimeException e) {
// If something goes wrong with the surface (such
// as running out of memory), don't take down the
// entire system.
Slog.e(TAG, "Error setting matrix on surface surface" + title
- + " MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
+ + " MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
if (!recoveringMemory) {
mAnimator.reclaimSomeSurfaceMemory("matrix", true);
}
@@ -423,6 +418,10 @@
}
}
+ void getContainerRect(Rect rect) {
+ mAnimator.getContainerRect(rect);
+ }
+
boolean showRobustlyInTransaction() {
if (SHOW_TRANSACTIONS) logSurface(
"SHOW (performLayout)", null);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3821b9c..bbda1c6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1022,6 +1022,26 @@
*/
public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET =
"carrier_default_actions_on_reset_string_array";
+
+ /**
+ * Defines carrier-specific actions which act upon
+ * com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+ * used for customization of the default carrier app
+ * Format:
+ * {
+ * "true : CARRIER_ACTION_IDX_1",
+ * "false: CARRIER_ACTION_IDX_2"
+ * }
+ * Where {@code true} is a boolean indicates default network available/unavailable
+ * Where {@code CARRIER_ACTION_IDX} is an integer defined in
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
+ * Example:
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils
+ * #CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER enable the app as the default URL handler}
+ * @hide
+ */
+ public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE =
+ "carrier_default_actions_on_default_network_available_string_array";
/**
* Defines a list of acceptable redirection url for default carrier app
* @hides
@@ -1684,9 +1704,10 @@
sDefaults.putString(KEY_CARRIER_SETUP_APP_STRING, "");
sDefaults.putStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
new String[]{
- "com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:" +
- "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED," +
- "com.android.internal.telephony.CARRIER_SIGNAL_RESET"
+ "com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED,"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_RESET,"
+ + "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"
});
sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
@@ -1694,12 +1715,22 @@
// Default carrier app configurations
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY,
new String[]{
- "4, 1"
+ "9, 4, 1"
+ //9: CARRIER_ACTION_REGISTER_NETWORK_AVAIL
//4: CARRIER_ACTION_DISABLE_METERED_APNS
//1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
});
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET, new String[]{
- "6" //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+ "6, 8"
+ //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+ //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
+ });
+ sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_DEFAULT_NETWORK_AVAILABLE,
+ new String[] {
+ String.valueOf(false) + ": 7",
+ //7: CARRIER_ACTION_ENABLE_DEFAULT_URL_HANDLER
+ String.valueOf(true) + ": 8"
+ //8: CARRIER_ACTION_DISABLE_DEFAULT_URL_HANDLER
});
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b5b32e4..e334c63 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1642,8 +1642,7 @@
* @hide
*/
public String getNetworkCountryIso(int subId) {
- int phoneId = SubscriptionManager.getPhoneId(subId);
- return getNetworkCountryIsoForPhone(phoneId);
+ return getNetworkCountryIsoForPhone(getPhoneId(subId));
}
/**
@@ -1658,7 +1657,14 @@
*/
/** {@hide} */
public String getNetworkCountryIsoForPhone(int phoneId) {
- return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null)
+ return "";
+ return telephony.getNetworkCountryIsoForPhone(phoneId);
+ } catch (RemoteException ex) {
+ return "";
+ }
}
/** Network type is unknown */
@@ -6655,6 +6661,25 @@
}
/**
+ * Action set from carrier signalling broadcast receivers to start/stop reporting default
+ * network available events
+ * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * @param subId the subscription ID that this action applies to.
+ * @param report control start/stop reporting network status.
+ * @hide
+ */
+ public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.carrierActionReportDefaultNetworkStatus(subId, report);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#carrierActionReportDefaultNetworkStatus", e);
+ }
+ }
+
+ /**
* Get aggregated video call data usage since boot.
* Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
*
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index a0e5b7b..9262ec5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -377,6 +377,13 @@
Bundle getCellLocation(String callingPkg);
/**
+ * Returns the ISO country code equivalent of the current registered
+ * operator's MCC (Mobile Country Code).
+ * @see android.telephony.TelephonyManager#getNetworkCountryIso
+ */
+ String getNetworkCountryIsoForPhone(int phoneId);
+
+ /**
* Returns the neighboring cell information of the device.
*/
List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
@@ -1296,6 +1303,16 @@
void carrierActionSetRadioEnabled(int subId, boolean enabled);
/**
+ * Action set from carrier signalling broadcast receivers to start/stop reporting default
+ * network conditions.
+ * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * @param subId the subscription ID that this action applies to.
+ * @param report control start/stop reporting default network events.
+ * @hide
+ */
+ void carrierActionReportDefaultNetworkStatus(int subId, boolean report);
+
+ /**
* Get aggregated video call data usage since boot.
* Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
*
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 0343890..f29d993c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -447,6 +447,20 @@
"com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
/**
+ * <p>Broadcast Action: when system default network available/unavailable with
+ * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when
+ * other network becomes system default network, Wi-Fi for example.
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li>defaultNetworkAvailable</li><dd>A boolean indicates default network available.</dd>
+ * <li>subId</li><dd>Sub Id which associated the default data.</dd>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system. </p>
+ */
+ public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE =
+ "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+
+ /**
* <p>Broadcast Action: when framework reset all carrier actions on sim load or absent.
* intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app
* The intent will have the following extra values:</p>
@@ -465,7 +479,7 @@
public static final String EXTRA_APN_PROTO_KEY = "apnProto";
public static final String EXTRA_PCO_ID_KEY = "pcoId";
public static final String EXTRA_PCO_VALUE_KEY = "pcoValue";
-
+ public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable";
/**
* Broadcast action to trigger CI OMA-DM Session.
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index 46098cb..7ff0c72 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -877,7 +877,16 @@
}
bool ConfigDescription::Dominates(const ConfigDescription& o) const {
- if (*this == DefaultConfig() || *this == o) {
+ if (*this == o) {
+ return true;
+ }
+
+ // Locale de-duping is not-trivial, disable for now (b/62409213).
+ if (diff(o) & CONFIG_LOCALE) {
+ return false;
+ }
+
+ if (*this == DefaultConfig()) {
return true;
}
return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index e89c6be..efc523f 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -69,14 +69,12 @@
TEST(DominatorTreeTest, DefaultDominatesEverything) {
const ConfigDescription default_config = {};
const ConfigDescription land_config = test::ParseConfigOrDie("land");
- const ConfigDescription sw600dp_land_config =
- test::ParseConfigOrDie("sw600dp-land-v13");
+ const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
std::vector<std::unique_ptr<ResourceConfigValue>> configs;
configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
- configs.push_back(
- util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
+ configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
DominatorTree tree(configs);
PrettyPrinter printer;
@@ -91,16 +89,13 @@
TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
const ConfigDescription default_config = {};
const ConfigDescription land_config = test::ParseConfigOrDie("land");
- const ConfigDescription sw600dp_land_config =
- test::ParseConfigOrDie("sw600dp-land-v13");
+ const ConfigDescription sw600dp_land_config = test::ParseConfigOrDie("sw600dp-land-v13");
std::vector<std::unique_ptr<ResourceConfigValue>> configs;
configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
- configs.push_back(
- util::make_unique<ResourceConfigValue>(default_config, "phablet"));
- configs.push_back(
- util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
+ configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "phablet"));
+ configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
DominatorTree tree(configs);
PrettyPrinter printer;
@@ -118,16 +113,11 @@
const ConfigDescription en_config = test::ParseConfigOrDie("en");
const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
- const ConfigDescription ldrtl_xhdpi_config =
- test::ParseConfigOrDie("ldrtl-xhdpi-v4");
- const ConfigDescription sw300dp_config =
- test::ParseConfigOrDie("sw300dp-v13");
- const ConfigDescription sw540dp_config =
- test::ParseConfigOrDie("sw540dp-v14");
- const ConfigDescription sw600dp_config =
- test::ParseConfigOrDie("sw600dp-v14");
- const ConfigDescription sw720dp_config =
- test::ParseConfigOrDie("sw720dp-v13");
+ const ConfigDescription ldrtl_xhdpi_config = test::ParseConfigOrDie("ldrtl-xhdpi-v4");
+ const ConfigDescription sw300dp_config = test::ParseConfigOrDie("sw300dp-v13");
+ const ConfigDescription sw540dp_config = test::ParseConfigOrDie("sw540dp-v14");
+ const ConfigDescription sw600dp_config = test::ParseConfigOrDie("sw600dp-v14");
+ const ConfigDescription sw720dp_config = test::ParseConfigOrDie("sw720dp-v13");
const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
std::vector<std::unique_ptr<ResourceConfigValue>> configs;
@@ -135,8 +125,7 @@
configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
- configs.push_back(
- util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
+ configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
@@ -148,15 +137,37 @@
std::string expected =
"<default>\n"
- " en\n"
- " en-v21\n"
" ldrtl-v4\n"
" ldrtl-xhdpi-v4\n"
" sw300dp-v13\n"
" sw540dp-v14\n"
" sw600dp-v14\n"
" sw720dp-v13\n"
- " v20\n";
+ " v20\n"
+ "en\n"
+ " en-v21\n";
+ EXPECT_EQ(expected, printer.ToString(&tree));
+}
+
+TEST(DominatorTreeTest, LocalesAreNeverDominated) {
+ const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+ const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+ const ConfigDescription fr_rFR_config = test::ParseConfigOrDie("fr-rFR");
+
+ std::vector<std::unique_ptr<ResourceConfigValue>> configs;
+ configs.push_back(util::make_unique<ResourceConfigValue>(ConfigDescription::DefaultConfig(), ""));
+ configs.push_back(util::make_unique<ResourceConfigValue>(fr_config, ""));
+ configs.push_back(util::make_unique<ResourceConfigValue>(fr_rCA_config, ""));
+ configs.push_back(util::make_unique<ResourceConfigValue>(fr_rFR_config, ""));
+
+ DominatorTree tree(configs);
+ PrettyPrinter printer;
+
+ std::string expected =
+ "<default>\n"
+ "fr\n"
+ "fr-rCA\n"
+ "fr-rFR\n";
EXPECT_EQ(expected, printer.ToString(&tree));
}
diff --git a/tools/aapt2/optimize/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp
index 4d00fa6..d9f384c0 100644
--- a/tools/aapt2/optimize/ResourceDeduper_test.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp
@@ -19,69 +19,88 @@
#include "ResourceTable.h"
#include "test/Test.h"
+using ::aapt::test::HasValue;
+using ::testing::Not;
+
namespace aapt {
TEST(ResourceDeduperTest, SameValuesAreDeduped) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
const ConfigDescription default_config = {};
+ const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+ const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
const ConfigDescription en_config = test::ParseConfigOrDie("en");
const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
- // Chosen because this configuration is compatible with en.
+ // Chosen because this configuration is compatible with ldrtl/en.
const ConfigDescription land_config = test::ParseConfigOrDie("land");
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
- .AddString("android:string/dedupe", ResourceId{}, default_config,
- "dedupe")
- .AddString("android:string/dedupe", ResourceId{}, en_config, "dedupe")
- .AddString("android:string/dedupe", ResourceId{}, land_config,
- "dedupe")
- .AddString("android:string/dedupe2", ResourceId{}, default_config,
- "dedupe")
- .AddString("android:string/dedupe2", ResourceId{}, en_config,
- "dedupe")
- .AddString("android:string/dedupe2", ResourceId{}, en_v21_config,
- "keep")
- .AddString("android:string/dedupe2", ResourceId{}, land_config,
- "dedupe")
+ .AddString("android:string/dedupe", ResourceId{}, default_config, "dedupe")
+ .AddString("android:string/dedupe", ResourceId{}, ldrtl_config, "dedupe")
+ .AddString("android:string/dedupe", ResourceId{}, land_config, "dedupe")
+
+ .AddString("android:string/dedupe2", ResourceId{}, default_config, "dedupe")
+ .AddString("android:string/dedupe2", ResourceId{}, ldrtl_config, "dedupe")
+ .AddString("android:string/dedupe2", ResourceId{}, ldrtl_v21_config, "keep")
+ .AddString("android:string/dedupe2", ResourceId{}, land_config, "dedupe")
+
+ .AddString("android:string/dedupe3", ResourceId{}, default_config, "dedupe")
+ .AddString("android:string/dedupe3", ResourceId{}, en_config, "dedupe")
+ .AddString("android:string/dedupe3", ResourceId{}, en_v21_config, "dedupe")
.Build();
ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
- EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/dedupe", en_config));
- EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/dedupe", land_config));
- EXPECT_EQ(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/dedupe2", en_config));
- EXPECT_NE(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/dedupe2", en_v21_config));
+ EXPECT_THAT(table, Not(HasValue("android:string/dedupe", ldrtl_config)));
+ EXPECT_THAT(table, Not(HasValue("android:string/dedupe", land_config)));
+
+ EXPECT_THAT(table, HasValue("android:string/dedupe2", ldrtl_v21_config));
+ EXPECT_THAT(table, Not(HasValue("android:string/dedupe2", ldrtl_config)));
+
+ EXPECT_THAT(table, HasValue("android:string/dedupe3", default_config));
+ EXPECT_THAT(table, HasValue("android:string/dedupe3", en_config));
+ EXPECT_THAT(table, Not(HasValue("android:string/dedupe3", en_v21_config)));
}
TEST(ResourceDeduperTest, DifferentValuesAreKept) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
const ConfigDescription default_config = {};
- const ConfigDescription en_config = test::ParseConfigOrDie("en");
- const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
- // Chosen because this configuration is compatible with en.
+ const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl");
+ const ConfigDescription ldrtl_v21_config = test::ParseConfigOrDie("ldrtl-v21");
+ // Chosen because this configuration is compatible with ldrtl.
const ConfigDescription land_config = test::ParseConfigOrDie("land");
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
- .AddString("android:string/keep", ResourceId{}, default_config,
- "keep")
- .AddString("android:string/keep", ResourceId{}, en_config, "keep")
- .AddString("android:string/keep", ResourceId{}, en_v21_config,
- "keep2")
+ .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+ .AddString("android:string/keep", ResourceId{}, ldrtl_config, "keep")
+ .AddString("android:string/keep", ResourceId{}, ldrtl_v21_config, "keep2")
.AddString("android:string/keep", ResourceId{}, land_config, "keep2")
.Build();
ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
- EXPECT_NE(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/keep", en_config));
- EXPECT_NE(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/keep", en_v21_config));
- EXPECT_NE(nullptr, test::GetValueForConfig<String>(
- table.get(), "android:string/keep", land_config));
+ EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_config));
+ EXPECT_THAT(table, HasValue("android:string/keep", ldrtl_v21_config));
+ EXPECT_THAT(table, HasValue("android:string/keep", land_config));
+}
+
+TEST(ResourceDeduperTest, LocalesValuesAreKept) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ const ConfigDescription default_config = {};
+ const ConfigDescription fr_config = test::ParseConfigOrDie("fr");
+ const ConfigDescription fr_rCA_config = test::ParseConfigOrDie("fr-rCA");
+
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddString("android:string/keep", ResourceId{}, default_config, "keep")
+ .AddString("android:string/keep", ResourceId{}, fr_config, "keep")
+ .AddString("android:string/keep", ResourceId{}, fr_rCA_config, "keep")
+ .Build();
+
+ ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get()));
+ EXPECT_THAT(table, HasValue("android:string/keep", default_config));
+ EXPECT_THAT(table, HasValue("android:string/keep", fr_config));
+ EXPECT_THAT(table, HasValue("android:string/keep", fr_rCA_config));
}
} // namespace aapt
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 01b2d14..8efd56a 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -156,6 +156,23 @@
return arg.Equals(&a);
}
+MATCHER_P(StrValueEq, a,
+ std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
+ return *(arg.value) == a;
+}
+
+MATCHER_P(HasValue, name,
+ std::string(negation ? "does not have" : "has") + " value " +
+ ::testing::PrintToString(name)) {
+ return GetValueForConfig<Value>(&(*arg), name, {}) != nullptr;
+}
+
+MATCHER_P2(HasValue, name, config,
+ std::string(negation ? "does not have" : "has") + " value " +
+ ::testing::PrintToString(name) + " for config " + ::testing::PrintToString(config)) {
+ return GetValueForConfig<Value>(&(*arg), name, config) != nullptr;
+}
+
} // namespace test
} // namespace aapt