All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.android.server.timezonedetector.location.LocationTimeZoneProviderProxy Maven / Gradle / Ivy

/*
 * Copyright (C) 2020 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.timezonedetector.location;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Handler;
import android.os.RemoteCallback;
import android.util.IndentingPrintWriter;

import com.android.internal.annotations.GuardedBy;
import com.android.server.timezonedetector.Dumpable;

import java.util.Objects;

/**
 * System server-side proxy for ITimeZoneProvider implementations, i.e. this provides the system
 * server object used to communicate with a remote TimeZoneProvider over Binder, which could be
 * running in a different process. As TimeZoneProviders are bound / unbound this proxy will rebind
 * to the "best" available remote process.
 *
 * 

Threading guarantees provided / required by this interface: *

    *
  • All public methods defined by this class must be invoked using the {@link Handler} thread * from the {@link ThreadingDomain} passed to the constructor, excluding * {@link #dump(IndentingPrintWriter, String[])}
  • *
  • Non-static public methods that make binder calls to remote processes (e.g. * {@link #setRequest(TimeZoneProviderRequest)}) are executed asynchronously and will return * immediately.
  • *
  • Callbacks received via binder are delivered via {@link Listener} are delivered on the * {@link Handler} thread from the {@link ThreadingDomain} passed to the constructor. *
* *

This class exists to enable the introduction of test implementations of {@link * LocationTimeZoneProviderProxy} that can be used when a device is in a test mode to inject test * events / behavior that are otherwise difficult to simulate. */ abstract class LocationTimeZoneProviderProxy implements Dumpable { @NonNull protected final Context mContext; @NonNull protected final ThreadingDomain mThreadingDomain; @NonNull protected final Object mSharedLock; // Non-null and effectively final after setListener() is called. @GuardedBy("mSharedLock") @Nullable protected Listener mListener; LocationTimeZoneProviderProxy( @NonNull Context context, @NonNull ThreadingDomain threadingDomain) { mContext = Objects.requireNonNull(context); mThreadingDomain = Objects.requireNonNull(threadingDomain); mSharedLock = threadingDomain.getLockObject(); } /** * Initializes the proxy. The supplied listener can expect to receive all events after this * point. This method calls {@link #onInitialize()} for subclasses to handle their own * initialization. */ void initialize(@NonNull Listener listener) { Objects.requireNonNull(listener); synchronized (mSharedLock) { if (mListener != null) { throw new IllegalStateException("listener already set"); } this.mListener = listener; onInitialize(); } } /** * Implemented by subclasses to initializes the proxy. This is called after {@link #mListener} * is set. */ @GuardedBy("mSharedLock") abstract void onInitialize(); /** * Destroys the proxy. This method calls {@link #onDestroy()} for subclasses to handle their own * destruction. */ void destroy() { synchronized (mSharedLock) { onDestroy(); } } /** * Implemented by subclasses to destroy the proxy. */ @GuardedBy("mSharedLock") abstract void onDestroy(); /** * Sets a new request for the provider. */ abstract void setRequest(@NonNull TimeZoneProviderRequest request); /** * Processes the supplied test command. An optional callback can be supplied to listen for a * response. */ abstract void handleTestCommand(@NonNull TestCommand testCommand, @Nullable RemoteCallback callback); /** * Handles a {@link TimeZoneProviderEvent} from a remote process. */ final void handleTimeZoneProviderEvent(@NonNull TimeZoneProviderEvent timeZoneProviderEvent) { // These calls are invoked on a binder thread. Move to the mThreadingDomain thread as // required by the guarantees for this class. mThreadingDomain.post(() -> mListener.onReportTimeZoneProviderEvent(timeZoneProviderEvent)); } /** * Interface for listening to location time zone providers. See {@link * LocationTimeZoneProviderProxy} for threading guarantees. */ interface Listener { /** * Called when a provider receives a {@link TimeZoneProviderEvent}. */ void onReportTimeZoneProviderEvent(@NonNull TimeZoneProviderEvent timeZoneProviderEvent); /** * Called when a provider is (re)bound. */ void onProviderBound(); /** Called when a provider is unbound. */ void onProviderUnbound(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy