Loading core/java/android/widget/AdapterViewFlipper.java +2 −39 Original line number Diff line number Diff line Loading @@ -16,10 +16,7 @@ package android.widget; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.os.Message; import android.util.AttributeSet; Loading Loading @@ -48,7 +45,6 @@ public class AdapterViewFlipper extends AdapterViewAnimator { private boolean mRunning = false; private boolean mStarted = false; private boolean mVisible = false; private boolean mUserPresent = true; private boolean mAdvancedByHost = false; public AdapterViewFlipper(Context context) { Loading Loading @@ -82,40 +78,10 @@ public class AdapterViewFlipper extends AdapterViewAnimator { a.recycle(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SCREEN_OFF.equals(action)) { mUserPresent = false; updateRunning(); } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(false); } } }; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); // OK, this is gross but needed. This class is supported by the // remote views machanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For exmaple, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); if (mAutoStart) { // Automatically start when requested startFlipping(); Loading @@ -126,8 +92,6 @@ public class AdapterViewFlipper extends AdapterViewAnimator { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; getContext().unregisterReceiver(mReceiver); updateRunning(); } Loading Loading @@ -235,8 +199,7 @@ public class AdapterViewFlipper extends AdapterViewAnimator { * true. */ private void updateRunning(boolean flipNow) { boolean running = !mAdvancedByHost && mVisible && mStarted && mUserPresent && mAdapter != null; boolean running = !mAdvancedByHost && mVisible && mStarted && mAdapter != null; if (running != mRunning) { if (running) { showOnly(mWhichChild, flipNow); Loading @@ -248,7 +211,7 @@ public class AdapterViewFlipper extends AdapterViewAnimator { } if (LOGD) { Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); + ", mRunning=" + mRunning); } } Loading core/java/android/widget/AnalogClock.java +18 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.BlendMode; Loading @@ -37,6 +36,9 @@ import android.view.RemotableViewMethod; import android.view.View; import android.view.inspector.InspectableProperty; import android.widget.RemoteViews.RemoteView; import android.widget.TextClock.ClockEventDelegate; import com.android.internal.util.Preconditions; import java.time.Clock; import java.time.DateTimeException; Loading Loading @@ -112,6 +114,7 @@ public class AnalogClock extends View { public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mClockEventDelegate = new ClockEventDelegate(context); mSecondsHandFps = AppGlobals.getIntCoreSetting( WidgetFlags.KEY_ANALOG_CLOCK_SECONDS_HAND_FPS, context.getResources() Loading Loading @@ -584,21 +587,9 @@ public class AnalogClock extends View { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); IntentFilter filter = new IntentFilter(); if (!mReceiverAttached) { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); // OK, this is gross but needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For example, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mIntentReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); mClockEventDelegate.registerTimeChangeReceiver(mIntentReceiver, getHandler()); mReceiverAttached = true; } Loading @@ -615,12 +606,23 @@ public class AnalogClock extends View { @Override protected void onDetachedFromWindow() { if (mReceiverAttached) { getContext().unregisterReceiver(mIntentReceiver); mClockEventDelegate.unregisterTimeChangeReceiver(mIntentReceiver); mReceiverAttached = false; } super.onDetachedFromWindow(); } /** * Sets a delegate to handle clock event registration. This must be called before the view is * attached to the window * * @hide */ public void setClockEventDelegate(ClockEventDelegate delegate) { Preconditions.checkState(!mReceiverAttached, "Clock events already registered"); mClockEventDelegate = delegate; } private void onVisible() { if (!mVisible) { mVisible = true; Loading Loading @@ -797,6 +799,7 @@ public class AnalogClock extends View { } }; private boolean mReceiverAttached; private ClockEventDelegate mClockEventDelegate; private final Runnable mTick = new Runnable() { @Override Loading core/java/android/widget/TextClock.java +85 −45 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.widget; import static android.os.Process.myUserHandle; import static android.view.ViewDebug.ExportedProperty; import static android.widget.RemoteViews.RemoteView; Loading @@ -24,7 +25,6 @@ import android.annotation.TestApi; import android.app.ActivityManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -43,6 +43,7 @@ import android.view.ViewHierarchyEncoder; import android.view.inspector.InspectableProperty; import com.android.internal.R; import com.android.internal.util.Preconditions; import java.time.Duration; import java.time.Instant; Loading Loading @@ -141,6 +142,8 @@ public class TextClock extends TextView { private boolean mRegistered; private boolean mShouldRunTicker; private ClockEventDelegate mClockEventDelegate; private Calendar mTime; private String mTimeZone; Loading Loading @@ -178,8 +181,7 @@ public class TextClock extends TextView { if (mTimeZone == null && Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { final String timeZone = intent.getStringExtra(Intent.EXTRA_TIMEZONE); createTime(timeZone); } else if (!mShouldRunTicker && (Intent.ACTION_TIME_TICK.equals(intent.getAction()) || Intent.ACTION_TIME_CHANGED.equals(intent.getAction()))) { } else if (!mShouldRunTicker && Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { return; } onTimeChanged(); Loading Loading @@ -282,6 +284,7 @@ public class TextClock extends TextView { if (mFormat24 == null) { mFormat24 = getBestDateTimePattern("Hm"); } mClockEventDelegate = new ClockEventDelegate(getContext()); createTime(mTimeZone); chooseFormat(); Loading Loading @@ -430,6 +433,17 @@ public class TextClock extends TextView { registerObserver(); } /** * Sets a delegate to handle clock event registration. This must be called before the view is * attached to the window * * @hide */ public void setClockEventDelegate(ClockEventDelegate delegate) { Preconditions.checkState(!mRegistered, "Clock events already registered"); mClockEventDelegate = delegate; } /** * Update the displayed time if necessary and invalidate the view. */ Loading Loading @@ -557,7 +571,7 @@ public class TextClock extends TextView { if (!mRegistered) { mRegistered = true; registerReceiver(); mClockEventDelegate.registerTimeChangeReceiver(mIntentReceiver, getHandler()); registerObserver(); createTime(mTimeZone); Loading @@ -582,7 +596,7 @@ public class TextClock extends TextView { super.onDetachedFromWindow(); if (mRegistered) { unregisterReceiver(); mClockEventDelegate.unregisterTimeChangeReceiver(mIntentReceiver); unregisterObserver(); mRegistered = false; Loading @@ -598,34 +612,11 @@ public class TextClock extends TextView { mStopTicking = true; } private void registerReceiver() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); // OK, this is gross but needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For example, when adding widgets from a managed profile to the // home screen. Therefore, we register the receiver as the user // the app is running as not the one the context is for. getContext().registerReceiverAsUser(mIntentReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); } private void registerObserver() { if (mRegistered) { if (mFormatChangeObserver == null) { mFormatChangeObserver = new FormatChangeObserver(getHandler()); } final ContentResolver resolver = getContext().getContentResolver(); Uri uri = Settings.System.getUriFor(Settings.System.TIME_12_24); if (mShowCurrentUserTime) { resolver.registerContentObserver(uri, true, mFormatChangeObserver, UserHandle.USER_ALL); } else { // UserHandle.myUserId() is needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app Loading @@ -634,20 +625,14 @@ public class TextClock extends TextView { // home screen. Therefore, we register the ContentObserver with the user // the app is running (e.g. the launcher) and not the user of the // context (e.g. the widget's profile). resolver.registerContentObserver(uri, true, mFormatChangeObserver, UserHandle.myUserId()); int userHandle = mShowCurrentUserTime ? UserHandle.USER_ALL : UserHandle.myUserId(); mClockEventDelegate.registerFormatChangeObserver(mFormatChangeObserver, userHandle); } } } private void unregisterReceiver() { getContext().unregisterReceiver(mIntentReceiver); } private void unregisterObserver() { if (mFormatChangeObserver != null) { final ContentResolver resolver = getContext().getContentResolver(); resolver.unregisterContentObserver(mFormatChangeObserver); mClockEventDelegate.unregisterFormatChangeObserver(mFormatChangeObserver); } } Loading @@ -674,4 +659,59 @@ public class TextClock extends TextView { stream.addProperty("format", mFormat == null ? null : mFormat.toString()); stream.addProperty("hasSeconds", mHasSeconds); } /** * Utility class to delegate some system event handling to allow overring the default behavior * * @hide */ public static class ClockEventDelegate { private final Context mContext; public ClockEventDelegate(Context context) { mContext = context; } /** * Registers a receiver for actions {@link Intent#ACTION_TIME_CHANGED} and * {@link Intent#ACTION_TIMEZONE_CHANGED} * * OK, this is gross but needed. This class is supported by the remote views mechanism and * as a part of that the remote views can be inflated by a context for another user without * the app having interact users permission - just for loading resources. For example, * when adding widgets from a managed profile to the home screen. Therefore, we register * the receiver as the user the app is running as not the one the context is for. */ public void registerTimeChangeReceiver(BroadcastReceiver receiver, Handler handler) { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); mContext.registerReceiverAsUser(receiver, myUserHandle(), filter, null, handler); } /** * Unregisters a previously registered receiver */ public void unregisterTimeChangeReceiver(BroadcastReceiver receiver) { mContext.unregisterReceiver(receiver); } /** * Registers an observer for time format changes */ public void registerFormatChangeObserver(ContentObserver observer, int userHandle) { Uri uri = Settings.System.getUriFor(Settings.System.TIME_12_24); mContext.getContentResolver().registerContentObserver(uri, true, observer, userHandle); } /** * Unregisters a previously registered observer */ public void unregisterFormatChangeObserver(ContentObserver observer) { mContext.getContentResolver().unregisterContentObserver(observer); } } } core/java/android/widget/ViewFlipper.java +2 −38 Original line number Diff line number Diff line Loading @@ -18,10 +18,7 @@ package android.widget; import android.annotation.IntRange; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.os.Build; import android.os.Message; Loading Loading @@ -51,8 +48,6 @@ public class ViewFlipper extends ViewAnimator { private boolean mRunning = false; private boolean mStarted = false; private boolean mVisible = false; @UnsupportedAppUsage private boolean mUserPresent = true; public ViewFlipper(Context context) { super(context); Loading @@ -70,39 +65,10 @@ public class ViewFlipper extends ViewAnimator { a.recycle(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SCREEN_OFF.equals(action)) { mUserPresent = false; updateRunning(); } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(false); } } }; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); // OK, this is gross but needed. This class is supported by the // remote views machanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For exmaple, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); if (mAutoStart) { // Automatically start when requested startFlipping(); Loading @@ -113,8 +79,6 @@ public class ViewFlipper extends ViewAnimator { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; getContext().unregisterReceiver(mReceiver); updateRunning(); } Loading Loading @@ -186,7 +150,7 @@ public class ViewFlipper extends ViewAnimator { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateRunning(boolean flipNow) { boolean running = mVisible && mStarted && mUserPresent; boolean running = mVisible && mStarted; if (running != mRunning) { if (running) { showOnly(mWhichChild, flipNow); Loading @@ -198,7 +162,7 @@ public class ViewFlipper extends ViewAnimator { } if (LOGD) { Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); + ", mRunning=" + mRunning); } } Loading Loading
core/java/android/widget/AdapterViewFlipper.java +2 −39 Original line number Diff line number Diff line Loading @@ -16,10 +16,7 @@ package android.widget; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.os.Message; import android.util.AttributeSet; Loading Loading @@ -48,7 +45,6 @@ public class AdapterViewFlipper extends AdapterViewAnimator { private boolean mRunning = false; private boolean mStarted = false; private boolean mVisible = false; private boolean mUserPresent = true; private boolean mAdvancedByHost = false; public AdapterViewFlipper(Context context) { Loading Loading @@ -82,40 +78,10 @@ public class AdapterViewFlipper extends AdapterViewAnimator { a.recycle(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SCREEN_OFF.equals(action)) { mUserPresent = false; updateRunning(); } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(false); } } }; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); // OK, this is gross but needed. This class is supported by the // remote views machanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For exmaple, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); if (mAutoStart) { // Automatically start when requested startFlipping(); Loading @@ -126,8 +92,6 @@ public class AdapterViewFlipper extends AdapterViewAnimator { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; getContext().unregisterReceiver(mReceiver); updateRunning(); } Loading Loading @@ -235,8 +199,7 @@ public class AdapterViewFlipper extends AdapterViewAnimator { * true. */ private void updateRunning(boolean flipNow) { boolean running = !mAdvancedByHost && mVisible && mStarted && mUserPresent && mAdapter != null; boolean running = !mAdvancedByHost && mVisible && mStarted && mAdapter != null; if (running != mRunning) { if (running) { showOnly(mWhichChild, flipNow); Loading @@ -248,7 +211,7 @@ public class AdapterViewFlipper extends AdapterViewAnimator { } if (LOGD) { Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); + ", mRunning=" + mRunning); } } Loading
core/java/android/widget/AnalogClock.java +18 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.BlendMode; Loading @@ -37,6 +36,9 @@ import android.view.RemotableViewMethod; import android.view.View; import android.view.inspector.InspectableProperty; import android.widget.RemoteViews.RemoteView; import android.widget.TextClock.ClockEventDelegate; import com.android.internal.util.Preconditions; import java.time.Clock; import java.time.DateTimeException; Loading Loading @@ -112,6 +114,7 @@ public class AnalogClock extends View { public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mClockEventDelegate = new ClockEventDelegate(context); mSecondsHandFps = AppGlobals.getIntCoreSetting( WidgetFlags.KEY_ANALOG_CLOCK_SECONDS_HAND_FPS, context.getResources() Loading Loading @@ -584,21 +587,9 @@ public class AnalogClock extends View { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); IntentFilter filter = new IntentFilter(); if (!mReceiverAttached) { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); // OK, this is gross but needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For example, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mIntentReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); mClockEventDelegate.registerTimeChangeReceiver(mIntentReceiver, getHandler()); mReceiverAttached = true; } Loading @@ -615,12 +606,23 @@ public class AnalogClock extends View { @Override protected void onDetachedFromWindow() { if (mReceiverAttached) { getContext().unregisterReceiver(mIntentReceiver); mClockEventDelegate.unregisterTimeChangeReceiver(mIntentReceiver); mReceiverAttached = false; } super.onDetachedFromWindow(); } /** * Sets a delegate to handle clock event registration. This must be called before the view is * attached to the window * * @hide */ public void setClockEventDelegate(ClockEventDelegate delegate) { Preconditions.checkState(!mReceiverAttached, "Clock events already registered"); mClockEventDelegate = delegate; } private void onVisible() { if (!mVisible) { mVisible = true; Loading Loading @@ -797,6 +799,7 @@ public class AnalogClock extends View { } }; private boolean mReceiverAttached; private ClockEventDelegate mClockEventDelegate; private final Runnable mTick = new Runnable() { @Override Loading
core/java/android/widget/TextClock.java +85 −45 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.widget; import static android.os.Process.myUserHandle; import static android.view.ViewDebug.ExportedProperty; import static android.widget.RemoteViews.RemoteView; Loading @@ -24,7 +25,6 @@ import android.annotation.TestApi; import android.app.ActivityManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -43,6 +43,7 @@ import android.view.ViewHierarchyEncoder; import android.view.inspector.InspectableProperty; import com.android.internal.R; import com.android.internal.util.Preconditions; import java.time.Duration; import java.time.Instant; Loading Loading @@ -141,6 +142,8 @@ public class TextClock extends TextView { private boolean mRegistered; private boolean mShouldRunTicker; private ClockEventDelegate mClockEventDelegate; private Calendar mTime; private String mTimeZone; Loading Loading @@ -178,8 +181,7 @@ public class TextClock extends TextView { if (mTimeZone == null && Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { final String timeZone = intent.getStringExtra(Intent.EXTRA_TIMEZONE); createTime(timeZone); } else if (!mShouldRunTicker && (Intent.ACTION_TIME_TICK.equals(intent.getAction()) || Intent.ACTION_TIME_CHANGED.equals(intent.getAction()))) { } else if (!mShouldRunTicker && Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { return; } onTimeChanged(); Loading Loading @@ -282,6 +284,7 @@ public class TextClock extends TextView { if (mFormat24 == null) { mFormat24 = getBestDateTimePattern("Hm"); } mClockEventDelegate = new ClockEventDelegate(getContext()); createTime(mTimeZone); chooseFormat(); Loading Loading @@ -430,6 +433,17 @@ public class TextClock extends TextView { registerObserver(); } /** * Sets a delegate to handle clock event registration. This must be called before the view is * attached to the window * * @hide */ public void setClockEventDelegate(ClockEventDelegate delegate) { Preconditions.checkState(!mRegistered, "Clock events already registered"); mClockEventDelegate = delegate; } /** * Update the displayed time if necessary and invalidate the view. */ Loading Loading @@ -557,7 +571,7 @@ public class TextClock extends TextView { if (!mRegistered) { mRegistered = true; registerReceiver(); mClockEventDelegate.registerTimeChangeReceiver(mIntentReceiver, getHandler()); registerObserver(); createTime(mTimeZone); Loading @@ -582,7 +596,7 @@ public class TextClock extends TextView { super.onDetachedFromWindow(); if (mRegistered) { unregisterReceiver(); mClockEventDelegate.unregisterTimeChangeReceiver(mIntentReceiver); unregisterObserver(); mRegistered = false; Loading @@ -598,34 +612,11 @@ public class TextClock extends TextView { mStopTicking = true; } private void registerReceiver() { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); // OK, this is gross but needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For example, when adding widgets from a managed profile to the // home screen. Therefore, we register the receiver as the user // the app is running as not the one the context is for. getContext().registerReceiverAsUser(mIntentReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); } private void registerObserver() { if (mRegistered) { if (mFormatChangeObserver == null) { mFormatChangeObserver = new FormatChangeObserver(getHandler()); } final ContentResolver resolver = getContext().getContentResolver(); Uri uri = Settings.System.getUriFor(Settings.System.TIME_12_24); if (mShowCurrentUserTime) { resolver.registerContentObserver(uri, true, mFormatChangeObserver, UserHandle.USER_ALL); } else { // UserHandle.myUserId() is needed. This class is supported by the // remote views mechanism and as a part of that the remote views // can be inflated by a context for another user without the app Loading @@ -634,20 +625,14 @@ public class TextClock extends TextView { // home screen. Therefore, we register the ContentObserver with the user // the app is running (e.g. the launcher) and not the user of the // context (e.g. the widget's profile). resolver.registerContentObserver(uri, true, mFormatChangeObserver, UserHandle.myUserId()); int userHandle = mShowCurrentUserTime ? UserHandle.USER_ALL : UserHandle.myUserId(); mClockEventDelegate.registerFormatChangeObserver(mFormatChangeObserver, userHandle); } } } private void unregisterReceiver() { getContext().unregisterReceiver(mIntentReceiver); } private void unregisterObserver() { if (mFormatChangeObserver != null) { final ContentResolver resolver = getContext().getContentResolver(); resolver.unregisterContentObserver(mFormatChangeObserver); mClockEventDelegate.unregisterFormatChangeObserver(mFormatChangeObserver); } } Loading @@ -674,4 +659,59 @@ public class TextClock extends TextView { stream.addProperty("format", mFormat == null ? null : mFormat.toString()); stream.addProperty("hasSeconds", mHasSeconds); } /** * Utility class to delegate some system event handling to allow overring the default behavior * * @hide */ public static class ClockEventDelegate { private final Context mContext; public ClockEventDelegate(Context context) { mContext = context; } /** * Registers a receiver for actions {@link Intent#ACTION_TIME_CHANGED} and * {@link Intent#ACTION_TIMEZONE_CHANGED} * * OK, this is gross but needed. This class is supported by the remote views mechanism and * as a part of that the remote views can be inflated by a context for another user without * the app having interact users permission - just for loading resources. For example, * when adding widgets from a managed profile to the home screen. Therefore, we register * the receiver as the user the app is running as not the one the context is for. */ public void registerTimeChangeReceiver(BroadcastReceiver receiver, Handler handler) { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); mContext.registerReceiverAsUser(receiver, myUserHandle(), filter, null, handler); } /** * Unregisters a previously registered receiver */ public void unregisterTimeChangeReceiver(BroadcastReceiver receiver) { mContext.unregisterReceiver(receiver); } /** * Registers an observer for time format changes */ public void registerFormatChangeObserver(ContentObserver observer, int userHandle) { Uri uri = Settings.System.getUriFor(Settings.System.TIME_12_24); mContext.getContentResolver().registerContentObserver(uri, true, observer, userHandle); } /** * Unregisters a previously registered observer */ public void unregisterFormatChangeObserver(ContentObserver observer) { mContext.getContentResolver().unregisterContentObserver(observer); } } }
core/java/android/widget/ViewFlipper.java +2 −38 Original line number Diff line number Diff line Loading @@ -18,10 +18,7 @@ package android.widget; import android.annotation.IntRange; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.os.Build; import android.os.Message; Loading Loading @@ -51,8 +48,6 @@ public class ViewFlipper extends ViewAnimator { private boolean mRunning = false; private boolean mStarted = false; private boolean mVisible = false; @UnsupportedAppUsage private boolean mUserPresent = true; public ViewFlipper(Context context) { super(context); Loading @@ -70,39 +65,10 @@ public class ViewFlipper extends ViewAnimator { a.recycle(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SCREEN_OFF.equals(action)) { mUserPresent = false; updateRunning(); } else if (Intent.ACTION_USER_PRESENT.equals(action)) { mUserPresent = true; updateRunning(false); } } }; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_USER_PRESENT); // OK, this is gross but needed. This class is supported by the // remote views machanism and as a part of that the remote views // can be inflated by a context for another user without the app // having interact users permission - just for loading resources. // For exmaple, when adding widgets from a user profile to the // home screen. Therefore, we register the receiver as the current // user not the one the context is for. getContext().registerReceiverAsUser(mReceiver, android.os.Process.myUserHandle(), filter, null, getHandler()); if (mAutoStart) { // Automatically start when requested startFlipping(); Loading @@ -113,8 +79,6 @@ public class ViewFlipper extends ViewAnimator { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; getContext().unregisterReceiver(mReceiver); updateRunning(); } Loading Loading @@ -186,7 +150,7 @@ public class ViewFlipper extends ViewAnimator { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void updateRunning(boolean flipNow) { boolean running = mVisible && mStarted && mUserPresent; boolean running = mVisible && mStarted; if (running != mRunning) { if (running) { showOnly(mWhichChild, flipNow); Loading @@ -198,7 +162,7 @@ public class ViewFlipper extends ViewAnimator { } if (LOGD) { Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted + ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning); + ", mRunning=" + mRunning); } } Loading