Merge "Replace IInterface::asBinder() with a static"
This commit is contained in:
commit
55f71bc080
@ -28,9 +28,9 @@ class IInterface : public virtual RefBase
|
||||
{
|
||||
public:
|
||||
IInterface();
|
||||
sp<IBinder> asBinder();
|
||||
sp<const IBinder> asBinder() const;
|
||||
|
||||
static sp<IBinder> asBinder(const IInterface*);
|
||||
static sp<IBinder> asBinder(const sp<IInterface>&);
|
||||
|
||||
protected:
|
||||
virtual ~IInterface();
|
||||
virtual IBinder* onAsBinder() = 0;
|
||||
|
@ -44,7 +44,7 @@ sp<IAppOpsService> AppOpsManager::getService()
|
||||
int64_t startTime = 0;
|
||||
mLock.lock();
|
||||
sp<IAppOpsService> service = mService;
|
||||
while (service == NULL || !service->asBinder()->isBinderAlive()) {
|
||||
while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
|
||||
sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
|
||||
if (binder == NULL) {
|
||||
// Wait for the app ops service to come back...
|
||||
|
@ -91,14 +91,14 @@ public:
|
||||
data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
|
||||
data.writeInt32(op);
|
||||
data.writeString16(packageName);
|
||||
data.writeStrongBinder(callback->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(callback));
|
||||
remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
|
||||
}
|
||||
|
||||
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(callback->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(callback));
|
||||
remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,18 @@ IInterface::IInterface()
|
||||
IInterface::~IInterface() {
|
||||
}
|
||||
|
||||
sp<IBinder> IInterface::asBinder()
|
||||
// static
|
||||
sp<IBinder> IInterface::asBinder(const IInterface* iface)
|
||||
{
|
||||
return onAsBinder();
|
||||
if (iface == NULL) return NULL;
|
||||
return const_cast<IInterface*>(iface)->onAsBinder();
|
||||
}
|
||||
|
||||
sp<const IBinder> IInterface::asBinder() const
|
||||
// static
|
||||
sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
|
||||
{
|
||||
return const_cast<IInterface*>(this)->onAsBinder();
|
||||
if (iface == NULL) return NULL;
|
||||
return iface->onAsBinder();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -216,7 +216,7 @@ status_t BnMemory::onTransact(
|
||||
CHECK_INTERFACE(IMemory, data, reply);
|
||||
ssize_t offset;
|
||||
size_t size;
|
||||
reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
|
||||
reply->writeStrongBinder( IInterface::asBinder(getMemory(&offset, &size)) );
|
||||
reply->writeInt32(offset);
|
||||
reply->writeInt32(size);
|
||||
return NO_ERROR;
|
||||
@ -241,7 +241,7 @@ BpMemoryHeap::~BpMemoryHeap() {
|
||||
if (mRealHeap) {
|
||||
// by construction we're the last one
|
||||
if (mBase != MAP_FAILED) {
|
||||
sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
|
||||
sp<IBinder> binder = IInterface::asBinder(this);
|
||||
|
||||
if (VERBOSE) {
|
||||
ALOGD("UNMAPPING binder=%p, heap=%p, size=%zu, fd=%d",
|
||||
@ -253,7 +253,7 @@ BpMemoryHeap::~BpMemoryHeap() {
|
||||
}
|
||||
} else {
|
||||
// remove from list only if it was mapped before
|
||||
sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
|
||||
sp<IBinder> binder = IInterface::asBinder(this);
|
||||
free_heap(binder);
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ BpMemoryHeap::~BpMemoryHeap() {
|
||||
void BpMemoryHeap::assertMapped() const
|
||||
{
|
||||
if (mHeapId == -1) {
|
||||
sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
|
||||
sp<IBinder> binder(IInterface::asBinder(const_cast<BpMemoryHeap*>(this)));
|
||||
sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
|
||||
heap->assertReallyMapped();
|
||||
if (heap->mBase != MAP_FAILED) {
|
||||
@ -297,7 +297,8 @@ void BpMemoryHeap::assertReallyMapped() const
|
||||
uint32_t offset = reply.readInt32();
|
||||
|
||||
ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)",
|
||||
asBinder().get(), parcel_fd, size, err, strerror(-err));
|
||||
IInterface::asBinder(this).get(),
|
||||
parcel_fd, size, err, strerror(-err));
|
||||
|
||||
int fd = dup( parcel_fd );
|
||||
ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
|
||||
@ -314,7 +315,7 @@ void BpMemoryHeap::assertReallyMapped() const
|
||||
mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
|
||||
if (mBase == MAP_FAILED) {
|
||||
ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
|
||||
asBinder().get(), size, fd, strerror(errno));
|
||||
IInterface::asBinder(this).get(), size, fd, strerror(errno));
|
||||
close(fd);
|
||||
} else {
|
||||
mSize = size;
|
||||
|
@ -87,7 +87,7 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
|
||||
}
|
||||
|
||||
// Is this a permission failure, or did the controller go away?
|
||||
if (pc->asBinder()->isBinderAlive()) {
|
||||
if (IInterface::asBinder(pc)->isBinderAlive()) {
|
||||
ALOGW("Permission failure: %s from uid=%d pid=%d",
|
||||
String8(permission).string(), uid, pid);
|
||||
return false;
|
||||
|
@ -774,8 +774,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
|
||||
// Set up a death notification so that we can disconnect
|
||||
// automatically if the remote producer dies
|
||||
if (listener != NULL &&
|
||||
listener->asBinder()->remoteBinder() != NULL) {
|
||||
status = listener->asBinder()->linkToDeath(
|
||||
IInterface::asBinder(listener)->remoteBinder() != NULL) {
|
||||
status = IInterface::asBinder(listener)->linkToDeath(
|
||||
static_cast<IBinder::DeathRecipient*>(this));
|
||||
if (status != NO_ERROR) {
|
||||
BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
|
||||
@ -824,7 +824,7 @@ status_t BufferQueueProducer::disconnect(int api) {
|
||||
// Remove our death notification callback if we have one
|
||||
if (mCore->mConnectedProducerListener != NULL) {
|
||||
sp<IBinder> token =
|
||||
mCore->mConnectedProducerListener->asBinder();
|
||||
IInterface::asBinder(mCore->mConnectedProducerListener);
|
||||
// This can fail if we're here because of the death
|
||||
// notification, but we just ignore it
|
||||
token->unlinkToDeath(
|
||||
|
@ -273,7 +273,7 @@ public:
|
||||
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(consumer->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(consumer));
|
||||
data.writeInt32(controlledByApp);
|
||||
status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
|
||||
if (result != NO_ERROR) {
|
||||
|
@ -211,7 +211,7 @@ public:
|
||||
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
||||
if (listener != NULL) {
|
||||
data.writeInt32(1);
|
||||
data.writeStrongBinder(listener->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(listener));
|
||||
} else {
|
||||
data.writeInt32(0);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ status_t BnSensorServer::onTransact(
|
||||
case CREATE_SENSOR_EVENT_CONNECTION: {
|
||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||
sp<ISensorEventConnection> connection(createSensorEventConnection());
|
||||
reply->writeStrongBinder(connection->asBinder());
|
||||
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(display);
|
||||
data.writeStrongBinder(producer->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(producer));
|
||||
data.write(sourceCrop);
|
||||
data.writeInt32(reqWidth);
|
||||
data.writeInt32(reqHeight);
|
||||
@ -137,7 +137,7 @@ public:
|
||||
"interface descriptor: %s (%d)", strerror(-err), -err);
|
||||
return false;
|
||||
}
|
||||
err = data.writeStrongBinder(bufferProducer->asBinder());
|
||||
err = data.writeStrongBinder(IInterface::asBinder(bufferProducer));
|
||||
if (err != NO_ERROR) {
|
||||
ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
|
||||
"strong binder to parcel: %s (%d)", strerror(-err), -err);
|
||||
@ -299,13 +299,13 @@ status_t BnSurfaceComposer::onTransact(
|
||||
switch(code) {
|
||||
case CREATE_CONNECTION: {
|
||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||
sp<IBinder> b = createConnection()->asBinder();
|
||||
sp<IBinder> b = IInterface::asBinder(createConnection());
|
||||
reply->writeStrongBinder(b);
|
||||
return NO_ERROR;
|
||||
}
|
||||
case CREATE_GRAPHIC_BUFFER_ALLOC: {
|
||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||
sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
|
||||
sp<IBinder> b = IInterface::asBinder(createGraphicBufferAlloc());
|
||||
reply->writeStrongBinder(b);
|
||||
return NO_ERROR;
|
||||
}
|
||||
@ -368,7 +368,7 @@ status_t BnSurfaceComposer::onTransact(
|
||||
case CREATE_DISPLAY_EVENT_CONNECTION: {
|
||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||
sp<IDisplayEventConnection> connection(createDisplayEventConnection());
|
||||
reply->writeStrongBinder(connection->asBinder());
|
||||
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||
return NO_ERROR;
|
||||
}
|
||||
case CREATE_DISPLAY: {
|
||||
|
@ -114,7 +114,7 @@ status_t BnSurfaceComposerClient::onTransact(
|
||||
status_t result = createSurface(name, w, h, format, flags,
|
||||
&handle, &gbp);
|
||||
reply->writeStrongBinder(handle);
|
||||
reply->writeStrongBinder(gbp != NULL ? gbp->asBinder() : NULL);
|
||||
reply->writeStrongBinder(IInterface::asBinder(gbp));
|
||||
reply->writeInt32(result);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
|
@ -63,7 +63,7 @@ status_t layer_state_t::read(const Parcel& input)
|
||||
}
|
||||
|
||||
status_t ComposerState::write(Parcel& output) const {
|
||||
output.writeStrongBinder(client->asBinder());
|
||||
output.writeStrongBinder(IInterface::asBinder(client));
|
||||
return state.write(output);
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ status_t ComposerState::read(const Parcel& input) {
|
||||
|
||||
status_t DisplayState::write(Parcel& output) const {
|
||||
output.writeStrongBinder(token);
|
||||
output.writeStrongBinder(surface != NULL ? surface->asBinder() : NULL);
|
||||
output.writeStrongBinder(IInterface::asBinder(surface));
|
||||
output.writeInt32(what);
|
||||
output.writeInt32(layerStack);
|
||||
output.writeInt32(orientation);
|
||||
|
@ -86,7 +86,7 @@ status_t SensorManager::assertStateLocked() const {
|
||||
};
|
||||
|
||||
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
|
||||
mSensorServer->asBinder()->linkToDeath(mDeathObserver);
|
||||
IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
|
||||
|
||||
mSensors = mSensorServer->getSensorList();
|
||||
size_t count = mSensors.size();
|
||||
|
@ -80,7 +80,7 @@ status_t StreamSplitter::addOutput(
|
||||
|
||||
IGraphicBufferProducer::QueueBufferOutput queueBufferOutput;
|
||||
sp<OutputListener> listener(new OutputListener(this, outputQueue));
|
||||
outputQueue->asBinder()->linkToDeath(listener);
|
||||
IInterface::asBinder(outputQueue)->linkToDeath(listener);
|
||||
status_t status = outputQueue->connect(listener, NATIVE_WINDOW_API_CPU,
|
||||
/* producerControlledByApp */ false, &queueBufferOutput);
|
||||
if (status != NO_ERROR) {
|
||||
|
@ -71,7 +71,7 @@ void ComposerService::connectLocked() {
|
||||
};
|
||||
|
||||
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
|
||||
mComposerService->asBinder()->linkToDeath(mDeathObserver);
|
||||
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
|
||||
}
|
||||
|
||||
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
|
||||
@ -462,14 +462,14 @@ status_t SurfaceComposerClient::initCheck() const {
|
||||
}
|
||||
|
||||
sp<IBinder> SurfaceComposerClient::connection() const {
|
||||
return (mClient != 0) ? mClient->asBinder() : 0;
|
||||
return IInterface::asBinder(mClient);
|
||||
}
|
||||
|
||||
status_t SurfaceComposerClient::linkToComposerDeath(
|
||||
const sp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie, uint32_t flags) {
|
||||
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
|
||||
return IInterface::asBinder(sm)->linkToDeath(recipient, cookie, flags);
|
||||
}
|
||||
|
||||
void SurfaceComposerClient::dispose() {
|
||||
|
@ -176,7 +176,7 @@ status_t SurfaceControl::writeSurfaceToParcel(
|
||||
if (control != NULL) {
|
||||
bp = control->mGraphicBufferProducer;
|
||||
}
|
||||
return parcel->writeStrongBinder(bp->asBinder());
|
||||
return parcel->writeStrongBinder(IInterface::asBinder(bp));
|
||||
}
|
||||
|
||||
sp<Surface> SurfaceControl::getSurface() const
|
||||
|
@ -87,8 +87,8 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
|
||||
sp<IGraphicBufferConsumer> consumer;
|
||||
BufferQueue::createBufferQueue(&producer, &consumer);
|
||||
sp<IServiceManager> serviceManager = defaultServiceManager();
|
||||
serviceManager->addService(PRODUCER_NAME, producer->asBinder());
|
||||
serviceManager->addService(CONSUMER_NAME, consumer->asBinder());
|
||||
serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
|
||||
serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
|
||||
ProcessState::self()->startThreadPool();
|
||||
IPCThreadState::self()->joinThreadPool();
|
||||
LOG_ALWAYS_FATAL("Shouldn't be here");
|
||||
|
@ -34,14 +34,14 @@ public:
|
||||
void registerListener(const sp<IBatteryPropertiesListener>& listener) {
|
||||
Parcel data;
|
||||
data.writeInterfaceToken(IBatteryPropertiesRegistrar::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(listener->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(listener));
|
||||
remote()->transact(REGISTER_LISTENER, data, NULL);
|
||||
}
|
||||
|
||||
void unregisterListener(const sp<IBatteryPropertiesListener>& listener) {
|
||||
Parcel data;
|
||||
data.writeInterfaceToken(IBatteryPropertiesRegistrar::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(listener->asBinder());
|
||||
data.writeStrongBinder(IInterface::asBinder(listener));
|
||||
remote()->transact(UNREGISTER_LISTENER, data, NULL);
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ MonitoredProducer::~MonitoredProducer() {
|
||||
wp<IBinder> mProducer;
|
||||
};
|
||||
|
||||
mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder()));
|
||||
mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder(this)));
|
||||
}
|
||||
|
||||
status_t MonitoredProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
|
||||
@ -111,7 +111,7 @@ void MonitoredProducer::allocateBuffers(bool async, uint32_t width,
|
||||
}
|
||||
|
||||
IBinder* MonitoredProducer::onAsBinder() {
|
||||
return mProducer->asBinder().get();
|
||||
return IInterface::asBinder(mProducer).get();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -496,7 +496,7 @@ size_t SurfaceFlinger::getMaxViewportDims() const {
|
||||
bool SurfaceFlinger::authenticateSurfaceTexture(
|
||||
const sp<IGraphicBufferProducer>& bufferProducer) const {
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
|
||||
sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
|
||||
return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
|
||||
}
|
||||
|
||||
@ -1273,10 +1273,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||
// this display is in both lists. see if something changed.
|
||||
const DisplayDeviceState& state(curr[j]);
|
||||
const wp<IBinder>& display(curr.keyAt(j));
|
||||
const sp<IBinder> state_binder =
|
||||
state.surface != NULL ? state.surface->asBinder() : NULL;
|
||||
const sp<IBinder> draw_binder =
|
||||
draw[i].surface != NULL ? draw[i].surface->asBinder() : NULL;
|
||||
const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
|
||||
const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
|
||||
if (state_binder != draw_binder) {
|
||||
// changing the surface is like destroying and
|
||||
// recreating the DisplayDevice, so we just remove it
|
||||
@ -1910,7 +1908,7 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client,
|
||||
// add this layer to the current state list
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
mCurrentState.layersSortedByZ.add(lbc);
|
||||
mGraphicBufferProducerList.add(gbc->asBinder());
|
||||
mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
|
||||
}
|
||||
|
||||
status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
|
||||
@ -1983,7 +1981,7 @@ void SurfaceFlinger::setTransactionState(
|
||||
// NOTE: it would be better to use RTTI as we could directly check
|
||||
// that we have a Client*. however, RTTI is disabled in Android.
|
||||
if (s.client != NULL) {
|
||||
sp<IBinder> binder = s.client->asBinder();
|
||||
sp<IBinder> binder = IInterface::asBinder(s.client);
|
||||
if (binder != NULL) {
|
||||
String16 desc(binder->getInterfaceDescriptor());
|
||||
if (desc == ISurfaceComposerClient::descriptor) {
|
||||
@ -2030,7 +2028,7 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
|
||||
if (disp.isValid()) {
|
||||
const uint32_t what = s.what;
|
||||
if (what & DisplayState::eSurfaceChanged) {
|
||||
if (disp.surface->asBinder() != s.surface->asBinder()) {
|
||||
if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
|
||||
disp.surface = s.surface;
|
||||
flags |= eDisplayTransactionNeeded;
|
||||
}
|
||||
@ -2921,7 +2919,7 @@ class GraphicProducerWrapper : public BBinder, public MessageHandler {
|
||||
// Prevent reads below from happening before the read from Message
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
if (what == MSG_API_CALL) {
|
||||
result = impl->asBinder()->transact(code, data[0], reply);
|
||||
result = IInterface::asBinder(impl)->transact(code, data[0], reply);
|
||||
barrier.open();
|
||||
} else if (what == MSG_EXIT) {
|
||||
exitRequested = true;
|
||||
@ -2971,7 +2969,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
||||
// if we have secure windows on this display, never allow the screen capture
|
||||
// unless the producer interface is local (i.e.: we can take a screenshot for
|
||||
// ourselves).
|
||||
if (!producer->asBinder()->localBinder()) {
|
||||
if (!IInterface::asBinder(producer)->localBinder()) {
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
sp<const DisplayDevice> hw(getDisplayDevice(display));
|
||||
if (hw->getSecureLayerVisible()) {
|
||||
@ -3035,7 +3033,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
|
||||
result = flinger->captureScreenImplLocked(hw, producer,
|
||||
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
|
||||
useIdentityTransform, rotation);
|
||||
static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
|
||||
static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user